Scro
Scro

Reputation: 1443

Method missing in User model, Rails 4.1

This should be easy but I'm obviously missing something. Working through a testing exercise, and attempting to create a method on the User model. Seems like it should be incredibly straightforward, but Rails is throwing method missing whenever I attempt to access the method.

Here's the code for the file app/models/user.rb:

class User < ActiveRecord::Base
  has_secure_password

  validates :email, presence: true, uniqueness: true

  def administrator?
  end
end

At this point I'm working through TDD process, and only attempting to satisfy the test exception by creating the method (I'll add code for the administrator? method later). Here's the line from the spec:

    expect(admin.administrator?).to be_true

And the output from the test:

1) User management adds a new user
 Failure/Error: expect(admin.administrator?).to be_true
   expected  to respond to `true?`

However, I can't seem to access the freaking method! Whenever I call the #administrator? method on an object of the User class I get:

NoMethodError: undefined method `administrator?' for #<User:0x007f9ac6929358>

Here's the pry response to 'ls -M' when I'm in the User class, showing the methods available:

User#methods: administrator  password  password_confirmation

Here's the output from a pry console session:

[73] pry(User):1> admin = User.first
User Load (0.2ms)  SELECT  "users".* FROM "users"   ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 1, email: "[email protected]", password_digest: "secret123", created_at: "2015-06-25 17:33:25", updated_at: "2015-06-25 17:33:25", admin: true, firstname: nil, lastname: nil>
[74] pry(User):1> admin.valid?
User Exists (0.2ms)  SELECT  1 AS one FROM "users"  WHERE ("users"."email" = '[email protected]' AND "users"."id" != 1) LIMIT 1
=> true
[75] pry(User):1> admin.instance_of?(User)
=> true
[76] pry(User):1> admin.administrator?
NoMethodError: undefined method `administrator?' for #<User:0x007f9ac6929358>
from /Users/me/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activemodel-4.1.1/lib/active_model/attribute_methods.rb:435:in `method_missing'

I've tried defining the method as self.administrator as well, with the same results. I went back and looked at the model methods defined in the Rails Tutorial, and I can't see anything about Hartl's model that helps me understand why my method isn't working.

Any help would be appreciated! I'm missing something basic here it seems...

**** EDIT/UPDATE **** After getting a response about how to return the boolean :admin column from the user object I realized that it's worth clarifying the real question. The real issue I was trying to understand isn't so much whether the administrator? method is the best way to determine whether a given user is an admin or not (as @sajinmp very helpfully points out below, the object will respond to admin? because of the corresponding column in the database).

My real question/frustration was with why I couldn't get the object to respond to that or any other methods created in the model.

Upvotes: 0

Views: 374

Answers (2)

Scro
Scro

Reputation: 1443

I restarted the Rails server, and that seemed to fix it. After cycling the server and starting a new console session, the user object now responds to the methods in user.rb.

Should have done that sooner (DUH!), but I'd assumed that it wouldn't be necessary. Within the console session I could use reload! and then the Pry show-source method would confirm that the methods were appearing in the console as written. I didn't think that the console relied on the server, but I must be wrong..?

Appreciate any confirmation on this.

Upvotes: 0

sajinmp
sajinmp

Reputation: 518

If all you are doing in the method is to check whether a user is an admin or not you do not need such a specific method. Since in your user model the administrator is represented by admin simply calling admin? is enough.

current_user.admin (<admin.admin> in this case) 

will answer your call. But when admin is nil this will be a problem so it is better to use

admin.try(:admin)

This will not throw an error even if admin is nil.

Upvotes: 1

Related Questions