1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #6800 from mschneider/dynamic_finders_for_aliased_attributes

Dynamic finders for aliased attributes
This commit is contained in:
Rafael Mendonça França 2012-06-22 07:51:11 -07:00
commit fb8cf55868
7 changed files with 27 additions and 2 deletions

View file

@ -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

View file

@ -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')

View file

@ -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?

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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