diff options
Diffstat (limited to 'activemodel/lib')
-rw-r--r-- | activemodel/lib/active_model/conversion.rb | 31 | ||||
-rw-r--r-- | activemodel/lib/active_model/dirty.rb | 6 | ||||
-rw-r--r-- | activemodel/lib/active_model/errors.rb | 191 | ||||
-rw-r--r-- | activemodel/lib/active_model/lint.rb | 45 | ||||
-rw-r--r-- | activemodel/lib/active_model/model.rb | 53 | ||||
-rw-r--r-- | activemodel/lib/active_model/naming.rb | 149 |
6 files changed, 357 insertions, 118 deletions
diff --git a/activemodel/lib/active_model/conversion.rb b/activemodel/lib/active_model/conversion.rb index d7f30f0920..89d87a8b6f 100644 --- a/activemodel/lib/active_model/conversion.rb +++ b/activemodel/lib/active_model/conversion.rb @@ -18,17 +18,23 @@ module ActiveModel # end # # cm = ContactMessage.new - # cm.to_model == self # => true - # cm.to_key # => nil - # cm.to_param # => nil - # cm.to_partial_path # => "contact_messages/contact_message" - # + # cm.to_model == cm # => true + # cm.to_key # => nil + # cm.to_param # => nil + # cm.to_partial_path # => "contact_messages/contact_message" module Conversion extend ActiveSupport::Concern # If your object is already designed to implement all of the Active Model # you can use the default <tt>:to_model</tt> implementation, which simply - # returns self. + # returns +self+. + # + # class Person + # include ActiveModel::Conversion + # end + # + # person = Person.new + # person.to_model == person # => true # # If your model does not act like an Active Model object, then you should # define <tt>:to_model</tt> yourself returning a proxy object that wraps @@ -37,21 +43,28 @@ module ActiveModel self end - # Returns an Enumerable of all key attributes if any is set, regardless - # if the object is persisted or not. + # Returns an Enumerable of all key attributes if any is set, regardless if + # the object is persisted or not. If there no key attributes, returns +nil+. def to_key key = respond_to?(:id) && id key ? [key] : nil end # Returns a string representing the object's key suitable for use in URLs, - # or nil if <tt>persisted?</tt> is false. + # or +nil+ if <tt>persisted?</tt> is false. def to_param persisted? ? to_key.join('-') : nil end # Returns a string identifying the path associated with the object. # ActionPack uses this to find a suitable partial to represent the object. + # + # class Person + # include ActiveModel::Conversion + # end + # + # person = Person.new + # person.to_partial_path # => "people/person" def to_partial_path self.class._to_partial_path end diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb index 7014d8114f..9bd5f903cd 100644 --- a/activemodel/lib/active_model/dirty.rb +++ b/activemodel/lib/active_model/dirty.rb @@ -80,8 +80,8 @@ module ActiveModel # person.changes # => {"name" => ["Bill", "Bob"]} # # If an attribute is modified in-place then make use of <tt>[attribute_name]_will_change!</tt> - # to mark that the attribute is changing. Otherwise ActiveModel can't track changes to - # in-place attributes. + # to mark that the attribute is changing. Otherwise ActiveModel can't track + # changes to in-place attributes. # # person.name_will_change! # person.name_change # => ["Bill", "Bill"] @@ -115,7 +115,7 @@ module ActiveModel end # Returns a hash of changed attributes indicating their original - # and new values like <tt>attr => [original value, new value]</tt>. + # and new values like <tt>attr => [original value, new value]</tt>. # # person.changes # => {} # person.name = 'bob' diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index 567677bbb9..4ed3462e7e 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -54,8 +54,8 @@ module ActiveModel # The above allows you to do: # # p = Person.new - # p.validate! # => ["can not be nil"] - # p.errors.full_messages # => ["name can not be nil"] + # person.validate! # => ["can not be nil"] + # person.errors.full_messages # => ["name can not be nil"] # # etc.. class Errors include Enumerable @@ -81,28 +81,50 @@ module ActiveModel super end - # Clear the messages + # Clear the error messages. + # + # person.errors.full_messages # => ["name can not be nil"] + # person.errors.clear + # person.errors.full_messages # => [] def clear messages.clear end - # Do the error messages include an error with key +error+? + # Returns +true+ if the error messages include an error for the given key + # +attribute+, +false+ otherwise. + # + # person.errors.messages # => { :name => ["can not be nil"] } + # person.errors.include?(:name) # => true + # person.errors.include?(:age) # => false def include?(attribute) (v = messages[attribute]) && v.any? end + # aliases include? alias :has_key? :include? - # Get messages for +key+ + # Get messages for +key+. + # + # person.errors.messages # => { :name => ["can not be nil"] } + # person.errors.get(:name) # => ["can not be nil"] + # person.errors.get(:age) # => nil def get(key) messages[key] end - # Set messages for +key+ to +value+ + # Set messages for +key+ to +value+. + # + # person.errors.get(:name) # => ["can not be nil"] + # person.errors.set(:name, ["can't be nil"]) + # person.errors.get(:name) # => ["can't be nil"] def set(key, value) messages[key] = value end - # Delete messages for +key+ + # Delete messages for +key+. Returns the deleted messages. + # + # person.errors.get(:name) # => ["can not be nil"] + # person.errors.delete(:name) # => ["can not be nil"] + # person.errors.get(:name) # => nil def delete(key) messages.delete(key) end @@ -110,16 +132,16 @@ module ActiveModel # When passed a symbol or a name of a method, returns an array of errors # for the method. # - # p.errors[:name] # => ["can not be nil"] - # p.errors['name'] # => ["can not be nil"] + # person.errors[:name] # => ["can not be nil"] + # person.errors['name'] # => ["can not be nil"] def [](attribute) get(attribute.to_sym) || set(attribute.to_sym, []) end # Adds to the supplied attribute the supplied error message. # - # p.errors[:name] = "must be set" - # p.errors[:name] # => ['must be set'] + # person.errors[:name] = "must be set" + # person.errors[:name] # => ['must be set'] def []=(attribute, error) self[attribute] << error end @@ -128,13 +150,13 @@ module ActiveModel # Yields the attribute and the error for that attribute. If the attribute # has more than one error message, yields once for each error message. # - # p.errors.add(:name, "can't be blank") - # p.errors.each do |attribute, error| + # person.errors.add(:name, "can't be blank") + # person.errors.each do |attribute, error| # # Will yield :name and "can't be blank" # end # - # p.errors.add(:name, "must be specified") - # p.errors.each do |attribute, error| + # person.errors.add(:name, "must be specified") + # person.errors.each do |attribute, error| # # Will yield :name and "can't be blank" # # then yield :name and "must be specified" # end @@ -146,54 +168,65 @@ module ActiveModel # Returns the number of error messages. # - # p.errors.add(:name, "can't be blank") - # p.errors.size # => 1 - # p.errors.add(:name, "must be specified") - # p.errors.size # => 2 + # person.errors.add(:name, "can't be blank") + # person.errors.size # => 1 + # person.errors.add(:name, "must be specified") + # person.errors.size # => 2 def size values.flatten.size end - # Returns all message values + # Returns all message values. + # + # person.errors.messages # => { :name => ["can not be nil", "must be specified"] } + # person.errors.values # => [["can not be nil", "must be specified"]] def values messages.values end - # Returns all message keys + # Returns all message keys. + # + # person.errors.messages # => { :name => ["can not be nil", "must be specified"] } + # person.errors.keys # => [:name] def keys messages.keys end - # Returns an array of error messages, with the attribute name included + # Returns an array of error messages, with the attribute name included. # - # p.errors.add(:name, "can't be blank") - # p.errors.add(:name, "must be specified") - # p.errors.to_a # => ["name can't be blank", "name must be specified"] + # person.errors.add(:name, "can't be blank") + # person.errors.add(:name, "must be specified") + # person.errors.to_a # => ["name can't be blank", "name must be specified"] def to_a full_messages end # Returns the number of error messages. - # p.errors.add(:name, "can't be blank") - # p.errors.count # => 1 - # p.errors.add(:name, "must be specified") - # p.errors.count # => 2 + # + # person.errors.add(:name, "can't be blank") + # person.errors.count # => 1 + # person.errors.add(:name, "must be specified") + # person.errors.count # => 2 def count to_a.size end - # Returns true if no errors are found, false otherwise. + # Returns +true+ if no errors are found, +false+ otherwise. # If the error message is a string it can be empty. + # + # person.errors.full_messages # => ["name can not be nil"] + # person.errors.empty? # => false def empty? all? { |k, v| v && v.empty? && !v.is_a?(String) } end + # aliases empty? alias_method :blank?, :empty? # Returns an xml formatted representation of the Errors hash. # - # p.errors.add(:name, "can't be blank") - # p.errors.add(:name, "must be specified") - # p.errors.to_xml + # person.errors.add(:name, "can't be blank") + # person.errors.add(:name, "must be specified") + # person.errors.to_xml # # => # # <?xml version=\"1.0\" encoding=\"UTF-8\"?> # # <errors> @@ -204,14 +237,21 @@ module ActiveModel to_a.to_xml({ :root => "errors", :skip_types => true }.merge!(options)) end - # Returns an Hash that can be used as the JSON representation for this object. - # Options: - # * <tt>:full_messages</tt> - determines if json object should contain - # full messages or not. Default: <tt>false</tt>. + # Returns a Hash that can be used as the JSON representation for this + # object. You can pass the <tt>:full_messages</tt> option. This determines + # if the json object should contain full messages or not (false by default). + # + # person.as_json # => { :name => ["can not be nil"] } + # person.as_json(full_messages: true) # => { :name => ["name can not be nil"] } def as_json(options=nil) to_hash(options && options[:full_messages]) end + # Returns a Hash of attributes with their error messages. If +full_messages+ + # is +true+, it will contain full messages (see +full_message+). + # + # person.to_hash # => { :name => ["can not be nil"] } + # person.to_hash(true) # => { :name => ["name can not be nil"] } def to_hash(full_messages = false) if full_messages messages = {} @@ -224,12 +264,31 @@ module ActiveModel end end - # Adds +message+ to the error messages on +attribute+. More than one error can be added to the same - # +attribute+. - # If no +message+ is supplied, <tt>:invalid</tt> is assumed. + # Adds +message+ to the error messages on +attribute+. More than one error + # can be added to the same +attribute+. If no +message+ is supplied, + # <tt>:invalid</tt> is assumed. # - # If +message+ is a symbol, it will be translated using the appropriate scope (see +generate_message+). - # If +message+ is a proc, it will be called, allowing for things like <tt>Time.now</tt> to be used within an error. + # person.errors.add(:name) + # # => ["is invalid"] + # person.errors.add(:name, 'must be implemented') + # # => ["is invalid", "must be implemented"] + # + # person.errors.messages + # # => { :name => ["must be implemented", "is invalid"] } + # + # If +message+ is a symbol, it will be translated using the appropriate + # scope (see +generate_message+). + # + # If +message+ is a proc, it will be called, allowing for things like + # <tt>Time.now</tt> to be used within an error. + # + # If the <tt>:strict</tt> option is set to true will raise + # ActiveModel::StrictValidationFailed instead of adding the error. + # + # person.errors.add(:name, nil, strict: true) + # # => ActiveModel::StrictValidationFailed: name is invalid + # + # person.errors.messages # => {} def add(attribute, message = nil, options = {}) message = normalize_message(attribute, message, options) if options[:strict] @@ -239,7 +298,12 @@ module ActiveModel self[attribute] << message end - # Will add an error message to each of the attributes in +attributes+ that is empty. + # Will add an error message to each of the attributes in +attributes+ + # that is empty. + # + # person.errors.add_on_empty(:name) + # person.errors.messages + # # => { :name => ["can't be empty"] } def add_on_empty(attributes, options = {}) [attributes].flatten.each do |attribute| value = @base.send(:read_attribute_for_validation, attribute) @@ -248,7 +312,12 @@ module ActiveModel end end - # Will add an error message to each of the attributes in +attributes+ that is blank (using Object#blank?). + # Will add an error message to each of the attributes in +attributes+ that + # is blank (using Object#blank?). + # + # person.errors.add_on_blank(:name) + # person.errors.messages + # # => { :name => ["can't be blank"] } def add_on_blank(attributes, options = {}) [attributes].flatten.each do |attribute| value = @base.send(:read_attribute_for_validation, attribute) @@ -256,10 +325,11 @@ module ActiveModel end end - # Returns true if an error on the attribute with the given message is present, false otherwise. - # +message+ is treated the same as for +add+. - # p.errors.add :name, :blank - # p.errors.added? :name, :blank # => true + # Returns +true+ if an error on the attribute with the given message is + # present, +false+ otherwise. +message+ is treated the same as for +add+. + # + # person.errors.add :name, :blank + # person.errors.added? :name, :blank # => true def added?(attribute, message = nil, options = {}) message = normalize_message(attribute, message, options) self[attribute].include? message @@ -267,22 +337,21 @@ module ActiveModel # Returns all the full error messages in an array. # - # class Company + # class Person # validates_presence_of :name, :address, :email - # validates_length_of :name, :in => 5..30 + # validates_length_of :name, in: 5..30 # end # - # company = Company.create(:address => '123 First St.') - # company.errors.full_messages # => - # ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"] + # person = Person.create(address: '123 First St.') + # person.errors.full_messages + # # => ["Name is too short (minimum is 5 characters)", "Name can't be blank", "Email can't be blank"] def full_messages map { |attribute, message| full_message(attribute, message) } end # Returns a full message for a given attribute. # - # company.errors.full_message(:name, "is invalid") # => - # "Name is invalid" + # person.errors.full_message(:name, 'is invalid') # => "Name is invalid" def full_message(attribute, message) return message if attribute == :base attr_name = attribute.to_s.tr('.', '_').humanize @@ -298,10 +367,11 @@ module ActiveModel # (<tt>activemodel.errors.messages</tt>). # # Error messages are first looked up in <tt>models.MODEL.attributes.ATTRIBUTE.MESSAGE</tt>, - # if it's not there, it's looked up in <tt>models.MODEL.MESSAGE</tt> and if that is not - # there also, it returns the translation of the default message - # (e.g. <tt>activemodel.errors.messages.MESSAGE</tt>). The translated model name, - # translated attribute name and the value are available for interpolation. + # if it's not there, it's looked up in <tt>models.MODEL.MESSAGE</tt> and if + # that is not there also, it returns the translation of the default message + # (e.g. <tt>activemodel.errors.messages.MESSAGE</tt>). The translated model + # name, translated attribute name and the value are available for + # interpolation. # # When using inheritance in your models, it will check all the inherited # models too, but only if the model itself hasn't been found. Say you have @@ -317,7 +387,6 @@ module ActiveModel # * <tt>activemodel.errors.messages.blank</tt> # * <tt>errors.attributes.title.blank</tt> # * <tt>errors.messages.blank</tt> - # def generate_message(attribute, type = :invalid, options = {}) type = options.delete(:message) if options[:message].is_a?(Symbol) @@ -366,6 +435,8 @@ module ActiveModel end end + # Raised when a validation cannot be corrected by end users and are considered + # exceptional. class StrictValidationFailed < StandardError end end diff --git a/activemodel/lib/active_model/lint.rb b/activemodel/lib/active_model/lint.rb index 88b730626c..550fa474ea 100644 --- a/activemodel/lib/active_model/lint.rb +++ b/activemodel/lib/active_model/lint.rb @@ -12,19 +12,20 @@ module ActiveModel # you want all features out of the box. # # These tests do not attempt to determine the semantic correctness of the - # returned values. For instance, you could implement valid? to always - # return true, and the tests would pass. It is up to you to ensure that - # the values are semantically meaningful. + # returned values. For instance, you could implement <tt>valid?</tt> to + # always return true, and the tests would pass. It is up to you to ensure + # that the values are semantically meaningful. # - # Objects you pass in are expected to return a compliant object from a - # call to to_model. It is perfectly fine for to_model to return self. + # Objects you pass in are expected to return a compliant object from a call + # to <tt>to_model</tt>. It is perfectly fine for <tt>to_model</tt> to return + # +self+. module Tests # == Responds to <tt>to_key</tt> # # Returns an Enumerable of all (primary) key attributes - # or nil if model.persisted? is false. This is used by - # dom_id to generate unique ids for the object. + # or nil if <tt>model.persisted?</tt> is false. This is used by + # <tt>dom_id</tt> to generate unique ids for the object. def test_to_key assert model.respond_to?(:to_key), "The model should respond to to_key" def model.persisted?() false end @@ -34,13 +35,14 @@ module ActiveModel # == Responds to <tt>to_param</tt> # # Returns a string representing the object's key suitable for use in URLs - # or nil if model.persisted? is false. + # or +nil+ if <tt>model.persisted?</tt> is +false+. # - # Implementers can decide to either raise an exception or provide a default - # in case the record uses a composite primary key. There are no tests for this - # behavior in lint because it doesn't make sense to force any of the possible - # implementation strategies on the implementer. However, if the resource is - # not persisted?, then to_param should always return nil. + # Implementers can decide to either raise an exception or provide a + # default in case the record uses a composite primary key. There are no + # tests for this behavior in lint because it doesn't make sense to force + # any of the possible implementation strategies on the implementer. + # However, if the resource is not persisted?, then <tt>to_param</tt> + # should always return +nil+. def test_to_param assert model.respond_to?(:to_param), "The model should respond to to_param" def model.to_key() [1] end @@ -50,9 +52,8 @@ module ActiveModel # == Responds to <tt>to_partial_path</tt> # - # Returns a string giving a relative path. This is used for looking up + # Returns a string giving a relative path. This is used for looking up # partials. For example, a BlogPost model might return "blog_posts/blog_post" - # def test_to_partial_path assert model.respond_to?(:to_partial_path), "The model should respond to to_partial_path" assert_kind_of String, model.to_partial_path @@ -60,11 +61,11 @@ module ActiveModel # == Responds to <tt>persisted?</tt> # - # Returns a boolean that specifies whether the object has been persisted yet. - # This is used when calculating the URL for an object. If the object is - # not persisted, a form for that object, for instance, will route to the - # create action. If it is persisted, a form for the object will routes to - # the update action. + # Returns a boolean that specifies whether the object has been persisted + # yet. This is used when calculating the URL for an object. If the object + # is not persisted, a form for that object, for instance, will route to + # the create action. If it is persisted, a form for the object will routes + # to the update action. def test_persisted? assert model.respond_to?(:persisted?), "The model should respond to persisted?" assert_boolean model.persisted?, "persisted?" @@ -73,8 +74,8 @@ module ActiveModel # == Naming # # Model.model_name must return a string with some convenience methods: - # :human, :singular, and :plural. Check ActiveModel::Naming for more information. - # + # <tt>:human</tt>, <tt>:singular</tt> and <tt>:plural</tt>. Check + # ActiveModel::Naming for more information. def test_model_naming assert model.class.respond_to?(:model_name), "The model should respond to model_name" model_name = model.class.model_name diff --git a/activemodel/lib/active_model/model.rb b/activemodel/lib/active_model/model.rb index cb0a051ca5..33a530e6bd 100644 --- a/activemodel/lib/active_model/model.rb +++ b/activemodel/lib/active_model/model.rb @@ -2,11 +2,11 @@ module ActiveModel # == Active Model Basic Model # - # Includes the required interface for an object to interact with <tt>ActionPack</tt>, - # using different <tt>ActiveModel</tt> modules. It includes model name introspections, - # conversions, translations and validations. Besides that, it allows you to - # initialize the object with a hash of attributes, pretty much like - # <tt>ActiveRecord</tt> does. + # Includes the required interface for an object to interact with + # <tt>ActionPack</tt>, using different <tt>ActiveModel</tt> modules. + # It includes model name introspections, conversions, translations and + # validations. Besides that, it allows you to initialize the object with a + # hash of attributes, pretty much like <tt>ActiveRecord</tt> does. # # A minimal implementation could be: # @@ -15,13 +15,13 @@ module ActiveModel # attr_accessor :name, :age # end # - # person = Person.new(:name => 'bob', :age => '18') + # person = Person.new(name: 'bob', age: '18') # person.name # => 'bob' - # person.age # => 18 + # person.age # => 18 # - # Note that, by default, <tt>ActiveModel::Model</tt> implements <tt>persisted?</tt> to - # return <tt>false</tt>, which is the most common case. You may want to override it - # in your class to simulate a different scenario: + # Note that, by default, <tt>ActiveModel::Model</tt> implements <tt>persisted?</tt> + # to return +false+, which is the most common case. You may want to override + # it in your class to simulate a different scenario: # # class Person # include ActiveModel::Model @@ -32,11 +32,12 @@ module ActiveModel # end # end # - # person = Person.new(:id => 1, :name => 'bob') + # person = Person.new(id: 1, name: 'bob') # person.persisted? # => true # - # Also, if for some reason you need to run code on <tt>initialize</tt>, make sure you - # call super if you want the attributes hash initialization to happen. + # Also, if for some reason you need to run code on <tt>initialize</tt>, make + # sure you call +super+ if you want the attributes hash initialization to + # happen. # # class Person # include ActiveModel::Model @@ -48,11 +49,12 @@ module ActiveModel # end # end # - # person = Person.new(:id => 1, :name => 'bob') + # person = Person.new(id: 1, name: 'bob') # person.omg # => true # - # For more detailed information on other functionalities available, please refer - # to the specific modules included in <tt>ActiveModel::Model</tt> (see below). + # For more detailed information on other functionalities available, please + # refer to the specific modules included in <tt>ActiveModel::Model</tt> + # (see below). module Model def self.included(base) #:nodoc: base.class_eval do @@ -63,12 +65,31 @@ module ActiveModel end end + # Initializes a new model with the given +params+. + # + # class Person + # include ActiveModel::Model + # attr_accessor :name, :age + # end + # + # person = Person.new(name: 'bob', age: '18') + # person.name # => "bob" + # person.age # => 18 def initialize(params={}) params.each do |attr, value| self.public_send("#{attr}=", value) end if params end + # Indicates if the model is persisted. Default is +false+. + # + # class Person + # include ActiveModel::Model + # attr_accessor :id, :name + # end + # + # person = Person.new(id: 1, name: 'bob') + # person.persisted? # => false def persisted? false end diff --git a/activemodel/lib/active_model/naming.rb b/activemodel/lib/active_model/naming.rb index 2b5fc57a3a..ea4f9341c6 100644 --- a/activemodel/lib/active_model/naming.rb +++ b/activemodel/lib/active_model/naming.rb @@ -14,9 +14,137 @@ module ActiveModel alias_method :cache_key, :collection + ## + # :method: == + # + # :call-seq: + # ==(other) + # + # Equivalent to <tt>String#==</tt>. Returns +true+ if the class name and + # +other+ are equal, otherwise +false+. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name == 'BlogPost' # => true + # BlogPost.model_name == 'Blog Post' # => false + + ## + # :method: === + # + # :call-seq: + # ===(other) + # + # Equivalent to <tt>#==</tt>. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name === 'BlogPost' # => true + # BlogPost.model_name === 'Blog Post' # => false + + ## + # :method: <=> + # + # :call-seq: + # ==(other) + # + # Equivalent to <tt>String#<=></tt>. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name <=> 'BlogPost' # => 0 + # BlogPost.model_name <=> 'Blog' # => 1 + # BlogPost.model_name <=> 'BlogPosts' # => -1 + + ## + # :method: =~ + # + # :call-seq: + # =~(regexp) + # + # Equivalent to <tt>String#=~</tt>. Match the class name against the given + # regexp. Returns the position where the match starts or +nil+ if there is + # no match. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name =~ /Post/ # => 4 + # BlogPost.model_name =~ /\d/ # => nil + + ## + # :method: !~ + # + # :call-seq: + # !~(regexp) + # + # Equivalent to <tt>String#!~</tt>. Match the class name against the given + # regexp. Returns +true+ if there is no match, otherwise +false+. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name !~ /Post/ # => false + # BlogPost.model_name !~ /\d/ # => true + + ## + # :method: eql? + # + # :call-seq: + # eql?(other) + # + # Equivalent to <tt>String#eql?</tt>. Returns +true+ if the class name and + # +other+ have the same length and content, otherwise +false+. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name.eql?('BlogPost') # => true + # BlogPost.model_name.eql?('Blog Post') # => false + + ## + # :method: to_s + # + # :call-seq: + # to_s() + # + # Returns the class name. + # + # class BlogPost + # extend ActiveModel::Naming + # end + # + # BlogPost.model_name.to_s # => "BlogPost" + + ## + # :method: to_str + # + # :call-seq: + # to_str() + # + # Equivalent to +to_s+. delegate :==, :===, :<=>, :=~, :"!~", :eql?, :to_s, :to_str, :to => :name + # Returns a new ActiveModel::Name instance. By default, the +namespace+ + # and +name+ option will take the namespace and name of the given class + # respectively. + # + # module Foo + # class Bar + # end + # end + # + # ActiveModel::Name.new(Foo::Bar).to_s + # # => "Foo::Bar" def initialize(klass, namespace = nil, name = nil) @name = name || klass.name @@ -38,7 +166,11 @@ module ActiveModel end # Transform the model name into a more humane format, using I18n. By default, - # it will underscore then humanize the class name + # it will underscore then humanize the class name. + # + # class BlogPost + # extend ActiveModel::Naming + # end # # BlogPost.model_name.human # => "Blog post" # @@ -82,11 +214,12 @@ module ActiveModel # BookModule::BookCover.model_name.i18n_key # => :"book_module/book_cover" # # Providing the functionality that ActiveModel::Naming provides in your object - # is required to pass the Active Model Lint test. So either extending the provided - # method below, or rolling your own is required. + # is required to pass the Active Model Lint test. So either extending the + # provided method below, or rolling your own is required. module Naming # Returns an ActiveModel::Name object for module. It can be - # used to retrieve all kinds of naming-related information. + # used to retrieve all kinds of naming-related information + # (See ActiveModel::Name for more information). def model_name @_model_name ||= begin namespace = self.parents.detect do |n| @@ -96,7 +229,7 @@ module ActiveModel end end - # Returns the plural class name of a record or class. Examples: + # Returns the plural class name of a record or class. # # ActiveModel::Naming.plural(post) # => "posts" # ActiveModel::Naming.plural(Highrise::Person) # => "highrise_people" @@ -104,7 +237,7 @@ module ActiveModel model_name_from_record_or_class(record_or_class).plural end - # Returns the singular class name of a record or class. Examples: + # Returns the singular class name of a record or class. # # ActiveModel::Naming.singular(post) # => "post" # ActiveModel::Naming.singular(Highrise::Person) # => "highrise_person" @@ -112,10 +245,10 @@ module ActiveModel model_name_from_record_or_class(record_or_class).singular end - # Identifies whether the class name of a record or class is uncountable. Examples: + # Identifies whether the class name of a record or class is uncountable. # # ActiveModel::Naming.uncountable?(Sheep) # => true - # ActiveModel::Naming.uncountable?(Post) => false + # ActiveModel::Naming.uncountable?(Post) # => false def self.uncountable?(record_or_class) plural(record_or_class) == singular(record_or_class) end |