Commit a294f41d2617c11734b018d5c5db7546836f5eb0

Authored by Braulio Bhavamitra
1 parent b4e6aa3b

rails4.2: migrate type casting as acts_as_having_settings

app/models/blog_archives_block.rb
@@ -15,7 +15,7 @@ class BlogArchivesBlock < Block @@ -15,7 +15,7 @@ class BlogArchivesBlock < Block
15 _('Blog posts') 15 _('Blog posts')
16 end 16 end
17 17
18 - settings_items :blog_id, Integer 18 + settings_items :blog_id, type: Integer
19 19
20 def blog 20 def blog
21 blog_id && owner.blogs.exists?(blog_id) ? owner.blogs.find(blog_id) : owner.blog 21 blog_id && owner.blogs.exists?(blog_id) ? owner.blogs.find(blog_id) : owner.blog
app/models/link_list_block.rb
@@ -41,7 +41,7 @@ class LinkListBlock < Block @@ -41,7 +41,7 @@ class LinkListBlock < Block
41 [N_('New window'), '_new'], 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 before_save do |block| 46 before_save do |block|
47 block.links = block.links.delete_if {|i| i[:name].blank? and i[:address].blank?} 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,7 +39,7 @@ class ProductsBlock < Block
39 link_to(_('View all products'), owner.public_profile_url.merge(:controller => 'catalog', :action => 'index')) 39 link_to(_('View all products'), owner.public_profile_url.merge(:controller => 'catalog', :action => 'index'))
40 end 40 end
41 41
42 - settings_items :product_ids, Array 42 + settings_items :product_ids, type: Array
43 def product_ids=(array) 43 def product_ids=(array)
44 self.settings[:product_ids] = array 44 self.settings[:product_ids] = array
45 if self.settings[:product_ids] 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 module ActsAsHavingSettings 22 module ActsAsHavingSettings
2 23
3 module ClassMethods 24 module ClassMethods
  25 +
4 def acts_as_having_settings(*args) 26 def acts_as_having_settings(*args)
5 options = args.last.is_a?(Hash) ? args.pop : {} 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 end 37 end
17 38
18 - def setting_changed?(setting_field) 39 + def setting_changed? setting_field
19 setting_field = setting_field.to_sym 40 setting_field = setting_field.to_sym
20 - changed_settings = self.changes['#{settings_field}'] 41 + changed_settings = self.changes[self.class.settings_field]
21 return false if changed_settings.nil? 42 return false if changed_settings.nil?
22 43
23 old_setting_value = changed_settings.first.nil? ? nil : changed_settings.first[setting_field] 44 old_setting_value = changed_settings.first.nil? ? nil : changed_settings.first[setting_field]
24 new_setting_value = changed_settings.last[setting_field] 45 new_setting_value = changed_settings.last[setting_field]
25 old_setting_value != new_setting_value 46 old_setting_value != new_setting_value
26 end 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 end 51 end
36 52
37 def settings_items(*names) 53 def settings_items(*names)
38 54
39 options = names.last.is_a?(Hash) ? names.pop : {} 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 names.each do |setting| 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 end 74 end
56 end 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 end 79 end
63 80
64 end 81 end
plugins/statistics/lib/statistics_block.rb
@@ -8,7 +8,7 @@ class StatisticsBlock &lt; Block @@ -8,7 +8,7 @@ class StatisticsBlock &lt; Block
8 settings_items :tag_counter, :default => true 8 settings_items :tag_counter, :default => true
9 settings_items :comment_counter, :default => true 9 settings_items :comment_counter, :default => true
10 settings_items :hit_counter, :default => false 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 attr_accessible :comment_counter, :community_counter, :user_counter, :enterprise_counter, :product_counter, :category_counter, :tag_counter, :hit_counter, :templates_ids_counter 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 &quot;../test_helper&quot; @@ -2,11 +2,12 @@ require_relative &quot;../test_helper&quot;
2 2
3 class ActsAsHavingSettingsTest < ActiveSupport::TestCase 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 class TestClass < Block 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 attr_accessible :flag, :name, :flag_disabled_by_default 11 attr_accessible :flag, :name, :flag_disabled_by_default
11 end 12 end
12 13
@@ -26,7 +27,7 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase @@ -26,7 +27,7 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase
26 assert !block.respond_to?(:limit) 27 assert !block.respond_to?(:limit)
27 assert !block.respond_to?(:limit=) 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 assert_respond_to block, :limit 32 assert_respond_to block, :limit
32 assert_respond_to block, :limit= 33 assert_respond_to block, :limit=
@@ -35,7 +36,7 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase @@ -35,7 +36,7 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase
35 block.limit = 10 36 block.limit = 10
36 assert_equal 10, block.limit 37 assert_equal 10, block.limit
37 38
38 - assert_equal({ :limit => 10}, block.settings) 39 + assert_equal({ limit: 10}, block.settings)
39 end 40 end
40 41
41 should 'properly save the settings' do 42 should 'properly save the settings' do
@@ -50,7 +51,7 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase @@ -50,7 +51,7 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase
50 51
51 should 'be able to specify default values' do 52 should 'be able to specify default values' do
52 block_class = Class.new(Block) 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 assert_equal 10, block_class.new.some_setting 55 assert_equal 10, block_class.new.some_setting
55 end 56 end
56 57
@@ -75,10 +76,9 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase @@ -75,10 +76,9 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase
75 assert_equal true, obj.flag 76 assert_equal true, obj.flag
76 end 77 end
77 78
78 - should 'symbolize keys when save' do 79 + should 'have keys as symbols' do
79 obj = TestClass.new 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 end 82 end
83 83
84 should 'setting_changed be true if a setting passed as parameter was changed' do 84 should 'setting_changed be true if a setting passed as parameter was changed' do
@@ -101,14 +101,14 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase @@ -101,14 +101,14 @@ class ActsAsHavingSettingsTest &lt; ActiveSupport::TestCase
101 end 101 end
102 102
103 should 'setting_changed be false if a setting passed as parameter was not changed but another setting is changed' do 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 obj.save 105 obj.save
106 obj.name = 'antoher nme' 106 obj.name = 'antoher nme'
107 assert !obj.setting_changed?('flag') 107 assert !obj.setting_changed?('flag')
108 end 108 end
109 109
110 should 'setting_changed be true for all changed fields' do 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 obj.save 112 obj.save
113 obj.name = 'another nme' 113 obj.name = 'another nme'
114 obj.flag = true 114 obj.flag = true