diff options
-rw-r--r-- | activemodel/lib/active_model/attribute_methods.rb | 4 | ||||
-rw-r--r-- | activemodel/test/cases/attribute_methods_test.rb | 9 | ||||
-rw-r--r-- | activerecord/lib/active_record/dynamic_matchers.rb | 1 | ||||
-rw-r--r-- | activerecord/test/cases/deprecated_dynamic_methods_test.rb | 3 | ||||
-rw-r--r-- | activerecord/test/cases/finder_respond_to_test.rb | 5 | ||||
-rw-r--r-- | activerecord/test/cases/finder_test.rb | 5 | ||||
-rw-r--r-- | activerecord/test/models/topic.rb | 2 |
7 files changed, 27 insertions, 2 deletions
diff --git a/activemodel/lib/active_model/attribute_methods.rb b/activemodel/lib/active_model/attribute_methods.rb index b5b50847c2..30f51e041f 100644 --- a/activemodel/lib/active_model/attribute_methods.rb +++ b/activemodel/lib/active_model/attribute_methods.rb @@ -61,7 +61,8 @@ module ActiveModel CALL_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?]?\z/ included do - class_attribute :attribute_method_matchers, instance_writer: false + class_attribute :attribute_aliases, :attribute_method_matchers, instance_writer: false + self.attribute_aliases = {} self.attribute_method_matchers = [ClassMethods::AttributeMethodMatcher.new] end @@ -192,6 +193,7 @@ module ActiveModel # person.nickname # => "Bob" # person.name # => "Bob" def alias_attribute(new_name, old_name) + self.attribute_aliases = attribute_aliases.merge(new_name.to_s => old_name.to_s) attribute_method_matchers.each do |matcher| matcher_new = matcher.method_name(new_name).to_s matcher_old = matcher.method_name(old_name).to_s diff --git a/activemodel/test/cases/attribute_methods_test.rb b/activemodel/test/cases/attribute_methods_test.rb index e2f2cecc09..baaf842222 100644 --- a/activemodel/test/cases/attribute_methods_test.rb +++ b/activemodel/test/cases/attribute_methods_test.rb @@ -154,6 +154,15 @@ class AttributeMethodsTest < ActiveModel::TestCase assert_equal "value of foo", ModelWithAttributes.new.foo end + test '#alias_attribute generates attribute_aliases lookup hash' do + klass = Class.new(ModelWithAttributes) do + define_attribute_methods :foo + alias_attribute :bar, :foo + end + + assert_equal({ "bar" => "foo" }, klass.attribute_aliases) + end + test '#define_attribute_methods generates attribute methods with spaces in their names' do ModelWithAttributesWithSpaces.define_attribute_methods(:'foo bar') diff --git a/activerecord/lib/active_record/dynamic_matchers.rb b/activerecord/lib/active_record/dynamic_matchers.rb index 23aaa319d8..a37cde77ee 100644 --- a/activerecord/lib/active_record/dynamic_matchers.rb +++ b/activerecord/lib/active_record/dynamic_matchers.rb @@ -53,6 +53,7 @@ module ActiveRecord @model = model @name = name.to_s @attribute_names = @name.match(self.class.pattern)[1].split('_and_') + @attribute_names.map! { |n| @model.attribute_aliases[n] || n } end def valid? diff --git a/activerecord/test/cases/deprecated_dynamic_methods_test.rb b/activerecord/test/cases/deprecated_dynamic_methods_test.rb index 7c108b983e..09ca61aa1b 100644 --- a/activerecord/test/cases/deprecated_dynamic_methods_test.rb +++ b/activerecord/test/cases/deprecated_dynamic_methods_test.rb @@ -524,7 +524,8 @@ class DynamicScopeMatchTest < ActiveRecord::TestCase end def test_scoped_by - match = ActiveRecord::DynamicMatchers::Method.match(nil, "scoped_by_age_and_sex_and_location") + model = stub(attribute_aliases: {}) + match = ActiveRecord::DynamicMatchers::Method.match(model, "scoped_by_age_and_sex_and_location") assert_not_nil match assert_equal %w(age sex location), match.attribute_names end diff --git a/activerecord/test/cases/finder_respond_to_test.rb b/activerecord/test/cases/finder_respond_to_test.rb index eedbaac3bd..9440cd429a 100644 --- a/activerecord/test/cases/finder_respond_to_test.rb +++ b/activerecord/test/cases/finder_respond_to_test.rb @@ -36,6 +36,11 @@ class FinderRespondToTest < ActiveRecord::TestCase assert_respond_to Topic, :find_by_title_and_author_name end + def test_should_respond_to_find_all_by_an_aliased_attribute + ensure_topic_method_is_not_cached(:find_by_heading) + assert_respond_to Topic, :find_by_heading + end + def test_should_respond_to_find_or_initialize_from_one_attribute ensure_topic_method_is_not_cached(:find_or_initialize_by_title) assert_respond_to Topic, :find_or_initialize_by_title diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index df21585961..e62d984ebd 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -535,6 +535,11 @@ class FinderTest < ActiveRecord::TestCase assert_raise(ActiveRecord::RecordNotFound) { Topic.find_by_title!("The First Topic!") } end + def test_find_by_one_attribute_that_is_an_alias + assert_equal topics(:first), Topic.find_by_heading("The First Topic") + assert_nil Topic.find_by_heading("The First Topic!") + end + def test_find_by_one_attribute_with_conditions assert_equal accounts(:rails_core_account), Account.where('firm_id = ?', 6).find_by_credit_limit(50) end diff --git a/activerecord/test/models/topic.rb b/activerecord/test/models/topic.rb index 079e403444..fb27c9d4f0 100644 --- a/activerecord/test/models/topic.rb +++ b/activerecord/test/models/topic.rb @@ -58,6 +58,8 @@ class Topic < ActiveRecord::Base id end + alias_attribute :heading, :title + before_validation :before_validation_for_transaction before_save :before_save_for_transaction before_destroy :before_destroy_for_transaction |