I'm a newbie on Ruby on Rails application, I have already created CRUD but still stacked in Login
& Logout
functionality.
This is my Sessions_controller:
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:passkey])
# Log the user in and redirect to the user's show page.
else
# Create an error message.
flash[:danger] = 'Invalid email/password combination' # Not quite right!
render 'new'
end
end
def destroy
end
This is my view: new.html.erb
<%= form_for(:session, url: login_path) do |f| %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :passkey%>
<%= f.password_field :passkey, class: 'form-control' %>
<%= f.submit "Log in", class: "btn btn-primary" %>
<% end %>
This is my model:
class User< ActiveRecord::Base
validates :first_name, :presence => true, :length => { :in => 3..20 }
validates :last_name, :presence => true, :length => { :in => 3..20 }
validates :email, :presence => true, :uniqueness => true, format: { with: /\A[^@\s]+@([^@.\s]+\.)+[^@.\s]+\z/ }
validates :passkey, :confirmation => true, :length => {:in => 6..20}
end
When I click Login button then showing this error:
NoMethodError in SessionsController#create
undefined method `authenticate' for #User:0x0000000d5c65e0>
How can I fix this error?
I'm using ruby 1.9.7
Rails 4.2.5
& mysql2
That would help me a lot, Please.
I'm newbie on ruby on rails application
This answer is going to be out of context, but if you're new, I'd most definitely recommend using Devise
over rolling your own authentication.
You can see a very good tutorial on how to use Devise here.
--
In short, Devise handles all the back-end for authentication; it's built on top of warden
and gives you pre-rolled sessions
& registrations
controllers.
I recommend Devise to you because you're new.
Creating your own authentication, whilst relatively simple, takes a lot of experience to understand. It seems from your question that you're following a tutorial or whatever, and don't really appreciate the underlying principles governing the process of authenticating a user.
I may be wrong, but if you implement Devise, get it working, then you're able to make your own afterwards...
If you wanted to use Devise
, you would do the following:
#Gemfile
gem 'devise', '~> 3.5', '>= 3.5.3'
$ rails generate devise:install
$ rails generate devise User
$ rake db:migrate
This will set up the default controllers
, routes
and warden strategies
for Devise; it will add itself to your Model
and should allow you to run your server and get the authentication working.
You'll want to use the devise helpers
to manage access to the different parts of your application:
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :authenticate_user! #-> user has to "login" to access app
end
In your views, you can use current_user
, user_signed_in?
and a bunch of other helpers to provide user-centric functionality:
#app/views/layouts/application.html.erb
<%= render partial "nav" if user_signed_in? %>
This is only my recommendation, it won't help you with your own implementation of your authentication. Of course, I'll delete the answer if inappropriate.
To fix the problem you have right now,
undefined method `authenticate'
This means you don't have an authenticate
instance method on your User
model. You need the following:
#app/models/user.rb
class User < ActiveRecord::Base
def authenticate
# do something
end
end
One suspects you're trying to invoke Warden's authenticate!
method
I don't have huge experience with Warden; you'll want to ensure you're calling the correct methods for it. Because it's rack middleware, all of the warden
helpers are available through env["warden"]
, so I suspect you'll be using something like:
#app/models/user.rb
class User < ActiveRecord::Base
def authenticate
env["warden"].authenticate! ....
end
end
Just add
has_secure_password
to your User model. Make sure you add
gem 'bcrypt-ruby'
to your gemfile.
add a field called "password_digest" with string in your User model.
That's it. Rails will handle User authentication for you like a charm and you will be able to use #authenticate method on your Model as well!
Edit: you can check out this project at github - Rails Project @ Github I have implemented authentication using Rails on this. Checkout user.rb, gemfile and user_controller.rb.
If you use the devise gem then you should not use the has_secure_password
method. You should use the valid_password?
method.
Well it seems your User
class is missing a authenticate
method. You should implement that.
In case you want to use the built in Rails authentication you should add has_secure_password validations: false
to your user model.
Ref: http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/InstanceMethodsOnActivation.html#method-i-authenticate
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With