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
| @@ -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 < Block | @@ -8,7 +8,7 @@ class StatisticsBlock < 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 "../test_helper" | @@ -2,11 +2,12 @@ require_relative "../test_helper" | ||
| 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 < ActiveSupport::TestCase | @@ -26,7 +27,7 @@ class ActsAsHavingSettingsTest < 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 < ActiveSupport::TestCase | @@ -35,7 +36,7 @@ class ActsAsHavingSettingsTest < 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 < ActiveSupport::TestCase | @@ -50,7 +51,7 @@ class ActsAsHavingSettingsTest < 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 < ActiveSupport::TestCase | @@ -75,10 +76,9 @@ class ActsAsHavingSettingsTest < 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 < ActiveSupport::TestCase | @@ -101,14 +101,14 @@ class ActsAsHavingSettingsTest < 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 |