Commit a294f41d2617c11734b018d5c5db7546836f5eb0
1 parent
b4e6aa3b
Exists in
master
and in
20 other branches
rails4.2: migrate type casting as acts_as_having_settings
Showing
6 changed files
with
68 additions
and
51 deletions
Show diff stats
app/models/blog_archives_block.rb
app/models/link_list_block.rb
... | ... | @@ -41,7 +41,7 @@ class LinkListBlock < Block |
41 | 41 | [N_('New window'), '_new'], |
42 | 42 | ] |
43 | 43 | |
44 | - settings_items :links, Array, :default => [] | |
44 | + settings_items :links, type: Array, :default => [] | |
45 | 45 | |
46 | 46 | before_save do |block| |
47 | 47 | block.links = block.links.delete_if {|i| i[:name].blank? and i[:address].blank?} | ... | ... |
app/models/products_block.rb
... | ... | @@ -39,7 +39,7 @@ class ProductsBlock < Block |
39 | 39 | link_to(_('View all products'), owner.public_profile_url.merge(:controller => 'catalog', :action => 'index')) |
40 | 40 | end |
41 | 41 | |
42 | - settings_items :product_ids, Array | |
42 | + settings_items :product_ids, type: Array | |
43 | 43 | def product_ids=(array) |
44 | 44 | self.settings[:product_ids] = array |
45 | 45 | if self.settings[:product_ids] | ... | ... |
lib/acts_as_having_settings.rb
1 | +# declare missing types | |
2 | +module ActiveRecord | |
3 | + module Type | |
4 | + class Symbol < Value | |
5 | + def cast_value value | |
6 | + value.to_sym | |
7 | + end | |
8 | + end | |
9 | + class Array < Value | |
10 | + def cast_value value | |
11 | + Array(value) | |
12 | + end | |
13 | + end | |
14 | + class Hash < Value | |
15 | + def cast_value value | |
16 | + Hash[value] | |
17 | + end | |
18 | + end | |
19 | + end | |
20 | +end | |
21 | + | |
1 | 22 | module ActsAsHavingSettings |
2 | 23 | |
3 | 24 | module ClassMethods |
25 | + | |
4 | 26 | def acts_as_having_settings(*args) |
5 | 27 | options = args.last.is_a?(Hash) ? args.pop : {} |
6 | - | |
7 | - settings_field = options[:field] || 'settings' | |
28 | + field = (options[:field] || :settings).to_sym | |
8 | 29 | |
9 | - class_eval <<-CODE | |
10 | - serialize :#{settings_field}, Hash | |
11 | - def self.settings_field | |
12 | - #{settings_field.inspect} | |
13 | - end | |
14 | - def #{settings_field} | |
15 | - self[:#{settings_field}] ||= Hash.new | |
30 | + serialize field, Hash | |
31 | + class_attribute :settings_field | |
32 | + self.settings_field = field | |
33 | + | |
34 | + class_eval do | |
35 | + def settings_field | |
36 | + self[self.class.settings_field] ||= Hash.new | |
16 | 37 | end |
17 | 38 | |
18 | - def setting_changed?(setting_field) | |
39 | + def setting_changed? setting_field | |
19 | 40 | setting_field = setting_field.to_sym |
20 | - changed_settings = self.changes['#{settings_field}'] | |
41 | + changed_settings = self.changes[self.class.settings_field] | |
21 | 42 | return false if changed_settings.nil? |
22 | 43 | |
23 | 44 | old_setting_value = changed_settings.first.nil? ? nil : changed_settings.first[setting_field] |
24 | 45 | new_setting_value = changed_settings.last[setting_field] |
25 | 46 | old_setting_value != new_setting_value |
26 | 47 | end |
48 | + end | |
27 | 49 | |
28 | - before_save :symbolize_settings_keys | |
29 | - private | |
30 | - def symbolize_settings_keys | |
31 | - self[:#{settings_field}] && self[:#{settings_field}].symbolize_keys! | |
32 | - end | |
33 | - CODE | |
34 | - settings_items(*args) | |
50 | + settings_items *args | |
35 | 51 | end |
36 | 52 | |
37 | 53 | def settings_items(*names) |
38 | 54 | |
39 | 55 | options = names.last.is_a?(Hash) ? names.pop : {} |
40 | - default = (!options[:default].nil?) ? options[:default].inspect : "val" | |
41 | - data_type = options[:type] || :string | |
56 | + default = if !options[:default].nil? then options[:default] else nil end | |
57 | + data_type = options[:type] | |
58 | + data_type = if data_type.present? then data_type.to_s.camelize.to_sym else :String end | |
59 | + data_type = ActiveRecord::Type.const_get(data_type).new | |
42 | 60 | |
43 | 61 | names.each do |setting| |
44 | - class_eval <<-CODE | |
45 | - def #{setting} | |
46 | - val = send(self.class.settings_field)[:#{setting}] | |
47 | - val.nil? ? (#{default}.is_a?(String) ? gettext(#{default}) : #{default}) : val | |
48 | - end | |
49 | - def #{setting}=(value) | |
50 | - h = send(self.class.settings_field).clone | |
51 | - h[:#{setting}] = self.class.acts_as_having_settings_type_cast(value, #{data_type.inspect}) | |
52 | - send(self.class.settings_field.to_s + '=', h) | |
53 | - end | |
54 | - CODE | |
62 | + # symbolize key | |
63 | + setting = setting.to_sym | |
64 | + | |
65 | + define_method setting do | |
66 | + h = send self.class.settings_field | |
67 | + val = h[setting] | |
68 | + if val.nil? then (if default.is_a? String then gettext default else default end) else val end | |
69 | + end | |
70 | + define_method "#{setting}=" do |value| | |
71 | + h = send self.class.settings_field | |
72 | + h[setting] = self.class.acts_as_having_settings_type_cast value, data_type | |
73 | + end | |
55 | 74 | end |
56 | 75 | end |
57 | 76 | |
58 | - def acts_as_having_settings_type_cast(value, type) | |
59 | - # FIXME creating a new instance at every call, will the garbage collector | |
60 | - # be able to cope with it? | |
61 | - ActiveRecord::ConnectionAdapters::Column.new(:dummy, nil, type.to_s).type_cast(value) | |
77 | + def acts_as_having_settings_type_cast value, type | |
78 | + type.send :cast_value, value | |
62 | 79 | end |
63 | 80 | |
64 | 81 | end | ... | ... |
plugins/statistics/lib/statistics_block.rb
... | ... | @@ -8,7 +8,7 @@ class StatisticsBlock < Block |
8 | 8 | settings_items :tag_counter, :default => true |
9 | 9 | settings_items :comment_counter, :default => true |
10 | 10 | settings_items :hit_counter, :default => false |
11 | - settings_items :templates_ids_counter, Hash, :default => {} | |
11 | + settings_items :templates_ids_counter, type: Hash, default: {} | |
12 | 12 | |
13 | 13 | attr_accessible :comment_counter, :community_counter, :user_counter, :enterprise_counter, :product_counter, :category_counter, :tag_counter, :hit_counter, :templates_ids_counter |
14 | 14 | ... | ... |
test/unit/acts_as_having_settings_test.rb
... | ... | @@ -2,11 +2,12 @@ require_relative "../test_helper" |
2 | 2 | |
3 | 3 | class ActsAsHavingSettingsTest < ActiveSupport::TestCase |
4 | 4 | |
5 | - # using Block class as a sample user of the module | |
5 | + # using Block class as a sample user of the module | |
6 | 6 | class TestClass < Block |
7 | - settings_items :flag, :type => :boolean | |
8 | - settings_items :flag_disabled_by_default, :type => :boolean, :default => false | |
9 | - settings_items :name, :type => :string, :default => N_('ENGLISH TEXT') | |
7 | + settings_items :flag, type: :boolean | |
8 | + settings_items :flag_disabled_by_default, type: :boolean, default: false | |
9 | + # to test that 'name' will be symbolized (see below) | |
10 | + settings_items 'name', type: :string, default: N_('ENGLISH TEXT') | |
10 | 11 | attr_accessible :flag, :name, :flag_disabled_by_default |
11 | 12 | end |
12 | 13 | |
... | ... | @@ -26,7 +27,7 @@ class ActsAsHavingSettingsTest < ActiveSupport::TestCase |
26 | 27 | assert !block.respond_to?(:limit) |
27 | 28 | assert !block.respond_to?(:limit=) |
28 | 29 | |
29 | - block_class.settings_items :limit | |
30 | + block_class.settings_items :limit, type: :integer | |
30 | 31 | |
31 | 32 | assert_respond_to block, :limit |
32 | 33 | assert_respond_to block, :limit= |
... | ... | @@ -35,7 +36,7 @@ class ActsAsHavingSettingsTest < ActiveSupport::TestCase |
35 | 36 | block.limit = 10 |
36 | 37 | assert_equal 10, block.limit |
37 | 38 | |
38 | - assert_equal({ :limit => 10}, block.settings) | |
39 | + assert_equal({ limit: 10}, block.settings) | |
39 | 40 | end |
40 | 41 | |
41 | 42 | should 'properly save the settings' do |
... | ... | @@ -50,7 +51,7 @@ class ActsAsHavingSettingsTest < ActiveSupport::TestCase |
50 | 51 | |
51 | 52 | should 'be able to specify default values' do |
52 | 53 | block_class = Class.new(Block) |
53 | - block_class.settings_items :some_setting, :default => 10 | |
54 | + block_class.settings_items :some_setting, default: 10 | |
54 | 55 | assert_equal 10, block_class.new.some_setting |
55 | 56 | end |
56 | 57 | |
... | ... | @@ -75,10 +76,9 @@ class ActsAsHavingSettingsTest < ActiveSupport::TestCase |
75 | 76 | assert_equal true, obj.flag |
76 | 77 | end |
77 | 78 | |
78 | - should 'symbolize keys when save' do | |
79 | + should 'have keys as symbols' do | |
79 | 80 | obj = TestClass.new |
80 | - obj.settings.expects(:symbolize_keys!).once | |
81 | - assert obj.save | |
81 | + assert obj.settings.all?{ |k,v| k.is_a? Symbol } | |
82 | 82 | end |
83 | 83 | |
84 | 84 | should 'setting_changed be true if a setting passed as parameter was changed' do |
... | ... | @@ -101,14 +101,14 @@ class ActsAsHavingSettingsTest < ActiveSupport::TestCase |
101 | 101 | end |
102 | 102 | |
103 | 103 | should 'setting_changed be false if a setting passed as parameter was not changed but another setting is changed' do |
104 | - obj = TestClass.new(:name => 'some name') | |
104 | + obj = TestClass.new(name: 'some name') | |
105 | 105 | obj.save |
106 | 106 | obj.name = 'antoher nme' |
107 | 107 | assert !obj.setting_changed?('flag') |
108 | 108 | end |
109 | 109 | |
110 | 110 | should 'setting_changed be true for all changed fields' do |
111 | - obj = TestClass.new(:name => 'some name', :flag => false) | |
111 | + obj = TestClass.new(name: 'some name', flag: false) | |
112 | 112 | obj.save |
113 | 113 | obj.name = 'another nme' |
114 | 114 | obj.flag = true | ... | ... |