Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

model_name is not an instance method but a Class method

#6561

In Rails API documentation, the 'model_name' is indicated among 'Public Instance methods' what means that the method should be called on a class instance (object of a Class); But a simple test prove the opposite, - it is a class method:

irb(main):002:0> u = User.create(:login=>'admin',:firstname=>'jean',:lastname=>'dupont',:email=>'dupont@gmail.com')
=> #<User id: 1, login: "admin", firstname: "jean", lastname: "dupont", email: "dupont@gmail.com", created_at: "2011-03-11 08:37:5
8", updated_at: "2011-03-11 08:37:58">
irb(main):003:0> u.model_name
NoMethodError: undefined method `model_name' for #<User:0x34b0060>
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/activemodel-3.0.5/lib/active_model/attribute_methods.rb:364:in `method_missing'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/activerecord-3.0.5/lib/active_record/attribute_methods.rb:46:in `method_missing'
        from (irb):3
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
        from C:/Ruby192/lib/ruby/gems/1.9.1/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
        from script/rails:6:in `require'
        from script/rails:6:in `<main>'
irb(main):004:0> User.model_name
=> "User"

Should it be changed in the documentation ?

Reported by Javix · March 11th, 2011 @ 08:51 AM

State: wontfix
Milestone: none
Assigned to: Xavier Noria Xavier Noria
Importance: Low

Activity

  1. Vijay Dev
    Vijay Dev
    • Assigned user set to Xavier Noria

    Hmm.. It is a method defined in the ActiveModel::Naming module which is extended in ActiveRecord to make the method available as a class method for the ActiveRecord classes. I assume the documentation shows it as a 'public instance method' of the module, which is right.

    March 11th, 2011 @ 10:10 AM

  2. Javix
    Javix

    As far as I understand, in any OO language, public instance method are called on an instance of a class, so in this case it is supposed to work like that:
    @@@code user = User.new
    user.model_name

    as no matter which instance method.
    But in reality it looks more like a public class method which are defined and can be called as follows:
    

    class User
    def self.model_name
    #bla-bla end

    end

    User.model_name

    And this is exactly what is happening. Or it is me who don't understand the difference preperly between instance methods and class methods. If it's the case, so correct me. If not, I'd modified the documentation so that it would be more clear.
    Regards
    

    March 11th, 2011 @ 11:09 AM

  3. Xavier Noria
    Xavier Noria
    • State changed from new to wontfix
    • Importance changed from to Low

    You're right, it is an instance method of the module it belongs to, which is ActiveModel::Naming.

    Now, as Vijay explains, that does not mean it is an instance method in classes that use the module. In particular, if the class uses extend, it becomes a class method in that class. It is still an instance method in the module.

    To be even more exact, model_name is indeed an instance method, but an instance method of the singleton class of ActiveRecord::Base, which is the class where ActiveModel::Naming is being included (that's what extend does). But anyway we understand what we mean by class methods.

    Unfortunately, documentation tools as of today are not smart enough to be able to list model_name as a class method of ActiveRecord::Base. I have a plan to try to get better docs in that sense, perhaps someday.

    March 11th, 2011 @ 11:22 AM

  4. Vijay Dev
    Vijay Dev

    In Ruby, modules and classes behave just the same (with a few differences of course). The method model_name is a public instance of the Naming module. You are right when you say that it looks more like a public class method. It is one for the User class in your eg. That's because the Naming module is extended by ActiveRecord::Base.

    When a module is extended in a class, all the instance methods of the module become accessible as class methods in that class. By contrast, when a module is included in a class, all the instance methods of the module become accessible as instance methods in that class.

    March 11th, 2011 @ 11:28 AM

  5. Vijay Dev
    Vijay Dev

    @Xavier: Opened up the page and kept on typing, I missed your update :)

    March 11th, 2011 @ 11:31 AM

  6. Javix
    Javix

    OK, thak you guys, it's clear for me now.

    March 11th, 2011 @ 12:58 PM