简体   繁体   中英

Rails + devise sign_in error

Devise throws:

"NoMethodError (undefined method `login' for #<ActionDispatch::Request:0x00000004e42d80>):
"

every time I try to log in. In this application "login" field is used as authentication key:

/config/initializers/devise.rb:

config.authentication_keys = [ :login ]

In session_controller.rb I used before_filter :

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:user) { |u| u.permit(:login, :password) }
  end

And my routes.rb :

devise_for :users, :controllers => { :sessions => 'sessions', :registrations => 'registrations', :invitations => 'users/invitations'}

This problem appeared after upgrade from Rails 3 to Rails 4. Can someone explain to me, what I'm doing wrong?

UPDATE

My bad. Found wrong parameter in devise initializer, set by my co-worker. Anyway i have error message:

NameError (undefined local variable or method `invitation_token' for #<User:0x0000000286c750>):
  app/controllers/sessions_controller.rb:6:in `create'

sessions#create:

  def create
    self.resource = warden.authenticate!(auth_options)
    sign_in(resource_name, resource)

    render :json => { :user_id => resource.id }, :status => :created
  end

UPDATE

Crap. My co-worker also changed database.yml to another DB. So this DB was not migrated to last state =. After rake db:migrate all works fine. Thanks to all.

The underlying issue here is generally that devise's invitable code is generated by an second step in your devise work flow, a generator that makes a second migration:

$ rails g devise_invitable:install
$ rails g devise_invitable User   (where User is my Model)
$ rake db:migrate

What you need to check for is if both migrations are in sync (in my case I reran the user migration but NOT the invitable migration and thus my user table was incorrect).

According to this link , you should create a login virtual attribute in the User model.

#Virtual attribute for authenticating by either username or email
#This is in addition to a real persisted field like 'username'
attr_accessor :login

Also add login to attr_accessible for rails 3

attr_accessible :login

You may also need to overwrite Devise's find_for_database_authentication method in User model (assuming it is activerecord)

# app/models/user.rb

    def self.find_first_by_auth_conditions(warden_conditions)
      conditions = warden_conditions.dup
      if login = conditions.delete(:login)
        where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
      else
        where(conditions).first
      end
    end

You may need to modify config/initializers/devise.rb to have

config.reset_password_keys = [ :login ]
config.confirmation_keys = [ :login ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM