Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #6800 from mschneider/dynamic_finders_for_aliased_…

…attributes

Dynamic finders for aliased attributes
  • Loading branch information...
commit fb8cf55868d555b7f06215db5976c8aaf083d30b 2 parents 9298d60 + f984b81
@rafaelfranca rafaelfranca authored
View
4 activemodel/lib/active_model/attribute_methods.rb
@@ -61,7 +61,8 @@ module AttributeMethods
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 @@ def attribute_method_affix(*affixes)
# 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
View
9 activemodel/test/cases/attribute_methods_test.rb
@@ -154,6 +154,15 @@ def foo
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')
View
1  activerecord/lib/active_record/dynamic_matchers.rb
@@ -53,6 +53,7 @@ def initialize(model, name)
@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?
View
3  activerecord/test/cases/deprecated_dynamic_methods_test.rb
@@ -524,7 +524,8 @@ def test_scoped_by_no_match
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
View
5 activerecord/test/cases/finder_respond_to_test.rb
@@ -36,6 +36,11 @@ def test_should_respond_to_find_by_two_attributes
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
View
5 activerecord/test/cases/finder_test.rb
@@ -535,6 +535,11 @@ def test_find_by_one_attribute_bang
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
View
2  activerecord/test/models/topic.rb
@@ -58,6 +58,8 @@ def topic_id
id
end
+ alias_attribute :heading, :title
+
before_validation :before_validation_for_transaction
before_save :before_save_for_transaction
before_destroy :before_destroy_for_transaction
Please sign in to comment.
Something went wrong with that request. Please try again.