Permalink
Browse files

Add method returning attribute names and aliases

This new api was added to help with wrapping all parameters related to a
model (both parameters matching attribute names and aliases).
  • Loading branch information...
1 parent 37e6201 commit 217e902ab756f2aafd42bf1a4362e03c0bd96745 @vanstee committed with May 8, 2013
View
@@ -7,4 +7,9 @@
*Nick Sutterer*
+* Add the `ActiveModel#attribute_method_names` method, which returns an
+ array of attribute names and aliases as strings.
+
+ *Patrick Van Stee*
+
Please check [4-0-stable](https://github.com/rails/rails/blob/4-0-stable/activemodel/CHANGELOG.md) for previous changes.
@@ -72,9 +72,10 @@ module AttributeMethods
CALL_COMPILABLE_REGEXP = /\A[a-zA-Z_]\w*[!?]?\z/
included do
- class_attribute :attribute_aliases, :attribute_method_matchers, instance_writer: false
+ class_attribute :attribute_aliases, :attribute_method_matchers, :defined_attribute_names, instance_writer: false
self.attribute_aliases = {}
self.attribute_method_matchers = [ClassMethods::AttributeMethodMatcher.new]
+ self.defined_attribute_names = []
end
module ClassMethods
@@ -276,6 +277,10 @@ def define_attribute_methods(*attr_names)
# person.name # => "Bob"
# person.name_short? # => true
def define_attribute_method(attr_name)
+ attr_name = attr_name.to_s
+
+ self.defined_attribute_names << attr_name unless defined_attribute_names.include?(attr_name)
+
attribute_method_matchers.each do |matcher|
method_name = matcher.method_name(attr_name)
@@ -285,10 +290,11 @@ def define_attribute_method(attr_name)
if respond_to?(generate_method, true)
send(generate_method, attr_name)
else
- define_proxy_call true, generated_attribute_methods, method_name, matcher.method_missing_target, attr_name.to_s
+ define_proxy_call true, generated_attribute_methods, method_name, matcher.method_missing_target, attr_name
end
end
end
+
attribute_method_matchers_cache.clear
end
@@ -322,6 +328,22 @@ def undefine_attribute_methods
attribute_method_matchers_cache.clear
end
+ # Returns an array of attribute names and aliases as strings.
+ #
+ # class Person
+ # include ActiveModel::AttributeMethods
+ #
+ # define_attribute_method :name
+ #
+ # alias_attribute :nickname, :name
+ # end
+ #
+ # Person.attribute_method_names
+ # # => ["name", "nickname"]
+ def attribute_method_names
+ defined_attribute_names + attribute_aliases.keys
+ end
+
# Returns true if the attribute methods defined have been generated.
def generated_attribute_methods #:nodoc:
@generated_attribute_methods ||= Module.new.tap { |mod| include mod }
@@ -186,6 +186,15 @@ def foo
assert_equal "value of end", ModelWithRubyKeywordNamedAttributes.new.to
end
+ test '#attribute_method_names returns attribute names and attribute aliases' do
+ klass = Class.new(ModelWithAttributes) do
+ define_attribute_methods :foo
+ alias_attribute :bar, :foo
+ end
+
+ assert_equal ["foo", "bar"], klass.attribute_method_names
+ end
+
test '#undefine_attribute_methods removes attribute methods' do
ModelWithAttributes.define_attribute_methods(:foo)
ModelWithAttributes.undefine_attribute_methods

0 comments on commit 217e902

Please sign in to comment.