Using Rails 3.1.3. I'm using the method of password authentication presented in railscast 270 to place the call to "has_secure_password":
class User < ActiveRecord::Base
has_secure_password
end
It works except for one extremely puzzling issue. The documentation states to use
user.authenticate("notright")
But I can't see where the authenticate method is declared. I looked in secure_password, and a seemingly equivalent method is:
# Returns self if the password is correct, otherwise false.
def get_logged_in_user(unencrypted_password)
if BCrypt::Password.new(password_digest) == unencrypted_password
self
else
false
end
end
Note, I'm trying to convert the example from the railstutorial.org (really wonderful), so there was quite a bit I had to change, and there could be something in my application that is conflicting. For example, I had previously had this line:
attr_accessor :password
And that prevented the declaration of password= from ever being called in secure_password, resulting in the db column for password_digest being nil. Removing this line fixed this problem.
Update: I created a brand new rails app with 3.1.3, and confirmed that the simplest case of running these two commands results in the error:
u = User.create(:username => "a", :password => "foobar", :password_confirmation => "foobar")
(0.1ms) BEGIN
SQL (0.2ms) INSERT INTO users (created_at, password_digest, updated_at, username) VALUES ('2011-12-21 05:18:17', '$2a$10$BbwHbq1bGwvQRgE0xK28VeP8K/lwY.VfLaLsMSs6ogNa1DucephnK', '2011-12-21 05:18:17', 'a')
(42.6ms) COMMIT
u.authenticate("foobar")
u.authenticate("foobar")
NoMethodError: undefined method authenticate' for #<User:0xa26e4cc>
from /home/justin/.rvm/gems/ruby-1.9.3-p0#testapp/gems/activemodel-3.1.3/lib/active_model/attribute_methods.rb:385:inmethod_missing'
from /home/justin/.rvm/gems/ruby-1.9.3-p0#testapp/gems/activerecord-3.1.3/lib/active_record/attribute_methods.rb:60:in method_missing'
from (irb):4
from /home/justin/.rvm/gems/ruby-1.9.3-p0#testapp/gems/railties-3.1.3/lib/rails/commands/console.rb:45:instart'
from /home/justin/.rvm/gems/ruby-1.9.3-p0#testapp/gems/railties-3.1.3/lib/rails/commands/console.rb:8:in start'
from /home/justin/.rvm/gems/ruby-1.9.3-p0#testapp/gems/railties-3.1.3/lib/rails/commands.rb:40:in'
from /home/justin/j/RubymineProjects/auth/script/rails:6:in require'
from /home/justin/j/RubymineProjects/auth/script/rails:6:in'
from -e:1:in load'
from -e:1:in'
UPDATE:
This is definitely some sort of issue with ruby 1.9.3. I tried the same gems out on 1.9.2 and I have no issues.
Adding an authenticate method as follows (source) solved it for me.
I'm using ruby 1.9.3 as well. I've not tried 1.9.2 as you have.
Upgrading to Ruby 1.9.3 solve the issue.
Related
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: "test#yahoo.com", 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" = 'test#yahoo.com' 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.
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.
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.
I recently upgraded an old Rails 2.3 app (Ruby 1.8.7) to Rails 3.2 / Ruby 1.9.3. When using ActiveRecord serialize and trying to access a serialized attribute, i get:
ActiveRecord::AttributeMethods::Serialization::Attribute returned.
.unserialize then returns the actual value.
The real strange thing is, that there a some models which have a normal behavior.
Can someone help me?
I now figured out when this problem happens, but i still dont know why:
This works:
User < ActiveRecord::Base
serialize :options, Hash
end
Options return {}
If i call the model itself before serialize, like that:
User < ActiveRecord::Base
USER_LIST = User.all.map {|u| [u.name, u.id]}
serialize :options, Hash
end
i get ActiveRecord::AttributeMethods::Serialization::Attribute
Anybody got an idea?
Try using unserialized_value rather than unserialize, so it doesn't matter whether or not it has already been unserialized. For reference, view the source for the unserialized_value method here http://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/Attribute.html
I'm using Devise (v2.1.2) with Omniauth for user verification. I'm working on a functional test for a controller that takes a JSON object as the POST body and thus using the technique from this question to set the raw POST body. This works fine for development, but when I run tests I get an exception on a method that's completely unauthenticated:
NoMethodError: undefined method `user' for nil:NilClass
Example test:
test "should be able to create an item" do
m = FactoryGirl.attributes_for(:item)
raw_post :create, {}, m.to_json
assert_response :success
end
None of my models have a user method, and nothing in this controller uses authentication, so I was pretty confused. A full stack trace shows that the error comes from the first line of this function in Devise:
def sign_out_all_scopes(lock=true)
users = Devise.mappings.keys.map { |s| warden.user(:scope => s, :run_callbacks => false) }
warden.raw_session.inspect
warden.logout
expire_devise_cached_variables!
warden.clear_strategies_cache!
warden.lock! if lock
users.any?
end
So it looks like in my functional tests (and only in my functional tests) the warden object is nil.
Why is this function being called on an unauthenticated request?
Why doesn't the warden object exist here?
What can I do to fix it?
No idea, Devise is doing its own thing.
See 1.
Include Devise::TestHelpers.
The Devise documentation says that you need to include the helpers in order to use them. It does not say that if you don't include the helpers your functional tests will fail, including those that don't use any authentication, but that's what happens.
(Note the JSON handling here, which I originally thought was the problem, ended up being just a red herring. Even with standard post or get you will have this problem.)
I get an error that look like this:
undefined method `post_image_will_change!' for #<Post:0xf4e9184>
app/controllers/posts_controller.rb:43:in `new'
app/controllers/posts_controller.rb:43:in `create'
I've included this in my "post" model:
attr_accessible :title, :name, :content, :post_image
mount_uploader :post_image, PostImageUploader
and in _form.html.erb I've added:
:html => { :multipart => true }
I looked CarrierWave Error but that doesn't help me.
Any clues of what generates that error? I've migrated the database and so forth (followed the railscasts guide on carrierwave exactly..)
The OP comments that he fixed it, however there's no answer set so I thought I'd add one for people coming across this in the future, which included myself until I figured it out :)
undefined method `x_will_change!' for # happens if you forget to add a column in your model's db table. If you have a model User and a AvatarUploader, with the uploader mounted as in the Carrierwave docs:
class User < ActiveRecord::Base
mount_uploader :avatar, AvatarUploader
end
Then the error will read
undefined method `avatar_will_change!' for #<User:0x00...>
To fix it (based on this example) add a column in a migration run the following in the console:
rails g migration AddAvatarToUsers avatar:string
This will generate the following migration:
class AddAvatarToUsers < ActiveRecord::Migration
def change
add_column :users, :avatar, :string
end
end
Then migrate to apply the change (again in the console):
rake db:migrate
I suppose that author just forgot to run:
rake db:migrate
ALso, if you met such error inside of your tests then you should run:
rake db:test:prepare
Also, for anyone getting this error on heroku, you need to run
heroku run rake db:migrate
and
heroku restart
in the terminal after adding/removing fields/tables from your database.
Kreek, this is obviously a minor oversight, as most people would have realized by now, you probably meant to run this command, as one should, outside the console, otherwise, one would get the following:
'NameError: undefined local variable or method `migrate' for main:Object'.
I had similar problem but mine was because I was copying and pasting codes and forgot to delete
mount_uploader :picture, PictureUploader
from my model which did not use pictures.
Hope this help others in future who could not figure out what happened
I am working with a book to teach myself Ruby-on-Rails. Ruby version is 1.2.3 and rubygems V 1.3.5.
I start the console by ruby script/console and enter:
user = User.new(:screen_name => "example",
?> :email => "exampleATexample.com",
?> :password => "example")
but instead of adding the data to the DB, I get the following:
NameError: undefined local variable or method 'within' for User:Class from D:/ruby/lib/gems/1.8/gems/activerecord-1.15.3/lib/active_record/base.rb:1235:in 'method_missing' from ./script/../config/../config/../app/modules/user.rb:13
I don't really understand what's going on. Any kind of help is much appreciated, thank you!
First, I believe you main Rails v 1.2.3, this is a very old version of Rails, don't use it.
Second thing, the command you entered has wrong Ruby syntax... try this instead:
user =User.new(:screen_name => "example", :email => "exampleATexample.com", :password => "example")
Third thing: please paste more code....
Also, just as a check.
Whenever something doesn't work in Rails that has to do with the database, make sure you run
rake db:migrate
Sometimes this can slip your mind and cause weird errors.
Also, just as a side note... I would make sure that you add some validations to your user model that requires a user to confirm their password and or email. It's generally a good practice.
validates_confirmation_of :password, :email
All the best with learning Rails. Make sure you take #dvyjones's advice and upgrade to the latest version of Rails... a lot has changed since v. 1.2.3