module ActiveAttr::Attributes::ClassMethods
Public Instance Methods
Defines an attribute
For each attribute that is defined, a getter and setter will be added as an instance method to the model. An {AttributeDefinition} instance will be added to result of the attributes class method.
@example Define an attribute.
attribute :name
@param (see AttributeDefinition#initialize)
@raise [DangerousAttributeError] if the attribute name conflicts with
existing methods
@return [AttributeDefinition] Attribute's definition
@since 0.2.0
# File lib/active_attr/attributes.rb, line 228 def attribute(name, options={}) if dangerous_attribute_method_name = dangerous_attribute?(name) raise DangerousAttributeError, %{an attribute method named "#{dangerous_attribute_method_name}" would conflict with an existing method} else attribute! name, options end end
Defines an attribute without checking for conflicts
Allows you to define an attribute whose methods will conflict with an existing method. For example, Ruby's Timeout library adds a timeout method to Object
. Attempting to define a timeout attribute using .attribute will raise a {DangerousAttributeError}, but .attribute! will not.
@example Define a dangerous attribute.
attribute! :timeout
@param (see AttributeDefinition#initialize)
@return [AttributeDefinition] Attribute's definition
@since 0.6.0
# File lib/active_attr/attributes.rb, line 252 def attribute!(name, options={}) AttributeDefinition.new(name, options).tap do |attribute_definition| attribute_name = attribute_definition.name.to_s # Force active model to generate attribute methods remove_instance_variable("@attribute_methods_generated") if instance_variable_defined?("@attribute_methods_generated") define_attribute_methods([attribute_definition.name]) unless attribute_names.include? attribute_name remove_instance_variable("@attribute_names") if instance_variable_defined?("@attribute_names") attributes[attribute_name] = attribute_definition end end
Returns an Array of attribute names as Strings
@example Get attribute names
Person.attribute_names
@return [Array<String>] The attribute names
@since 0.5.0
# File lib/active_attr/attributes.rb, line 271 def attribute_names @attribute_names ||= attributes.keys end
Returns a Hash of AttributeDefinition
instances
@example Get attribute definitions
Person.attributes
@return [ActiveSupport::HashWithIndifferentAccess{String => ActiveAttr::AttributeDefinition}]
The Hash of AttributeDefinition instances
@since 0.2.0
# File lib/active_attr/attributes.rb, line 284 def attributes @attributes ||= ActiveSupport::HashWithIndifferentAccess.new end
Determine if a given attribute name is dangerous
Some attribute names can cause conflicts with existing methods on an object. For example, an attribute named “timeout” would conflict with the timeout method that Ruby's Timeout library mixes into Object
.
@example Testing a harmless attribute
Person.dangerous_attribute? :name #=> false
@example Testing a dangerous attribute
Person.dangerous_attribute? :nil #=> "nil?"
@param name Attribute name
@return [false, String] False or the conflicting method name
@since 0.6.0
# File lib/active_attr/attributes.rb, line 306 def dangerous_attribute?(name) attribute_methods(name).detect do |method_name| allocate.respond_to?(method_name, true) end unless attribute_names.include? name.to_s end
Returns the class name plus its attribute names
@example Inspect the model's definition.
Person.inspect
@return [String] Human-readable presentation of the attributes
@since 0.2.0
# File lib/active_attr/attributes.rb, line 320 def inspect inspected_attributes = attribute_names.sort attributes_list = "(#{inspected_attributes.join(", ")})" unless inspected_attributes.empty? "#{name}#{attributes_list}" end
Protected Instance Methods
Assign a set of attribute definitions, used when subclassing models
@param [Array<ActiveAttr::AttributeDefinition>] attributes The
Array of AttributeDefinition instances
@since 0.2.2
# File lib/active_attr/attributes.rb, line 334 def attributes=(attributes) @attributes = attributes end
Overrides ActiveModel::AttributeMethods to backport 3.2 fix
# File lib/active_attr/attributes.rb, line 339 def instance_method_already_implemented?(method_name) generated_attribute_methods.method_defined?(method_name) end
Private Instance Methods
Expand an attribute name into its generated methods names
@since 0.6.0
# File lib/active_attr/attributes.rb, line 348 def attribute_methods(name) attribute_method_matchers.map { |matcher| matcher.method_name name } end
Ruby inherited hook to assign superclass attributes to subclasses
@since 0.2.2
# File lib/active_attr/attributes.rb, line 355 def inherited(subclass) super subclass.attributes = attributes.dup end