From 0f6145549f86407a544ad86ae0691007f0d21758 Mon Sep 17 00:00:00 2001 From: harada4atsushi Date: Sat, 19 Oct 2019 15:56:04 +0900 Subject: [PATCH 1/2] Make sure raise error if you try to overwrite field name that is already defined in Object --- lib/active_hash/base.rb | 3 +++ spec/active_hash/base_spec.rb | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/lib/active_hash/base.rb b/lib/active_hash/base.rb index dc960427..94321879 100644 --- a/lib/active_hash/base.rb +++ b/lib/active_hash/base.rb @@ -229,6 +229,9 @@ def validate_field(field_name) if [:attributes].include?(field_name.to_sym) raise ReservedFieldError.new("#{field_name} is a reserved field in ActiveHash. Please use another name.") end + if Object.instance_methods.include?(field_name.to_sym) + raise ReservedFieldError.new("#{field_name} is a defied method in Object. Please use another name.") + end end private :validate_field diff --git a/spec/active_hash/base_spec.rb b/spec/active_hash/base_spec.rb index 156939f8..61599182 100644 --- a/spec/active_hash/base_spec.rb +++ b/spec/active_hash/base_spec.rb @@ -104,6 +104,12 @@ class Country < ActiveHash::Base Country.field :attributes end.should raise_error(ActiveHash::ReservedFieldError) end + + it "blows up if you try to overwrite field name that is already defined in Object" do + proc do + Country.field :display + end.should raise_error(ActiveHash::ReservedFieldError) + end end describe ".data=" do From 50121efbc39b6f2c7b1acaf41d2c00ea68e4cf98 Mon Sep 17 00:00:00 2001 From: harada4atsushi Date: Sat, 7 Dec 2019 13:30:23 +0900 Subject: [PATCH 2/2] Allow override methods already defined in super class --- lib/active_hash/base.rb | 15 +++---- spec/active_hash/base_spec.rb | 74 ++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/lib/active_hash/base.rb b/lib/active_hash/base.rb index 94321879..b18b7f09 100644 --- a/lib/active_hash/base.rb +++ b/lib/active_hash/base.rb @@ -229,9 +229,6 @@ def validate_field(field_name) if [:attributes].include?(field_name.to_sym) raise ReservedFieldError.new("#{field_name} is a reserved field in ActiveHash. Please use another name.") end - if Object.instance_methods.include?(field_name.to_sym) - raise ReservedFieldError.new("#{field_name} is a defied method in Object. Please use another name.") - end end private :validate_field @@ -283,7 +280,7 @@ def add_default_value field_name, default_value end def define_getter_method(field, default_value) - unless instance_methods.include?(field.to_sym) + unless instance_methods(false).include?(field.to_sym) define_method(field) do attributes[field].nil? ? default_value : attributes[field] end @@ -294,7 +291,7 @@ def define_getter_method(field, default_value) def define_setter_method(field) method_name = :"#{field}=" - unless instance_methods.include?(method_name) + unless instance_methods(false).include?(method_name) define_method(method_name) do |new_val| @attributes[field] = new_val end @@ -305,7 +302,7 @@ def define_setter_method(field) def define_interrogator_method(field) method_name = :"#{field}?" - unless instance_methods.include?(method_name) + unless instance_methods(false).include?(method_name) define_method(method_name) do send(field).present? end @@ -316,7 +313,7 @@ def define_interrogator_method(field) def define_custom_find_method(field_name) method_name = :"find_by_#{field_name}" - unless singleton_methods.include?(method_name) + unless singleton_methods(false).include?(method_name) the_meta_class.instance_eval do define_method(method_name) do |*args| args.extract_options! @@ -331,9 +328,9 @@ def define_custom_find_method(field_name) def define_custom_find_all_method(field_name) method_name = :"find_all_by_#{field_name}" - unless singleton_methods.include?(method_name) + unless singleton_methods(false).include?(method_name) the_meta_class.instance_eval do - unless singleton_methods.include?(method_name) + unless singleton_methods(false).include?(method_name) define_method(method_name) do |*args| args.extract_options! identifier = args[0] diff --git a/spec/active_hash/base_spec.rb b/spec/active_hash/base_spec.rb index 61599182..d52a47c6 100644 --- a/spec/active_hash/base_spec.rb +++ b/spec/active_hash/base_spec.rb @@ -104,12 +104,6 @@ class Country < ActiveHash::Base Country.field :attributes end.should raise_error(ActiveHash::ReservedFieldError) end - - it "blows up if you try to overwrite field name that is already defined in Object" do - proc do - Country.field :display - end.should raise_error(ActiveHash::ReservedFieldError) - end end describe ".data=" do @@ -1178,41 +1172,57 @@ class Region < ActiveHash::Base end end - it "doesn't override methods already defined" do - Country.class_eval do - class << self - def find_by_name(name) - "find_by_name defined manually" + context "when Country already defined name methods" do + before do + Country.class_eval do + class << self + def find_by_name(name) + "find_by_name defined manually" + end + + def find_all_by_name(name) + "find_all_by_name defined manually" + end end - def find_all_by_name(name) - "find_all_by_name defined manually" + def name + "name defined manually" end - end - - def name - "name defined manually" - end - def name? - "name? defined manually" + def name? + "name? defined manually" + end end end - Country.find_by_name("foo").should == "find_by_name defined manually" - Country.find_all_by_name("foo").should == "find_all_by_name defined manually" - Country.new.name.should == "name defined manually" - Country.new.name?.should == "name? defined manually" + it "doesn't override methods already defined" do + Country.find_by_name("foo").should == "find_by_name defined manually" + Country.find_all_by_name("foo").should == "find_all_by_name defined manually" + Country.new.name.should == "name defined manually" + Country.new.name?.should == "name? defined manually" - Country.data = [ - {:name => "foo"} - ] + Country.data = [ + {:name => "foo"} + ] - Country.all - Country.find_by_name("foo").should == "find_by_name defined manually" - Country.find_all_by_name("foo").should == "find_all_by_name defined manually" - Country.new.name.should == "name defined manually" - Country.new.name?.should == "name? defined manually" + Country.all + Country.find_by_name("foo").should == "find_by_name defined manually" + Country.find_all_by_name("foo").should == "find_all_by_name defined manually" + Country.new.name.should == "name defined manually" + Country.new.name?.should == "name? defined manually" + end + + it "allow override methods already defined in super class" do + class Japan < Country + field :name + add name: "bar" + end + Japan.first.name.should == "bar" + Japan.find_by_name("bar").should be_a(Japan) + Japan.find_all_by_name("bar").should be_a(Array) + Japan.first.name.should == "bar" + Japan.first.name?.should be_truthy + end end end