对象:Class的Authlogic未定义方法`login_field'

时间:2011-05-25 20:31:48

标签: ruby-on-rails ruby-on-rails-3 authentication authlogic

我正在尝试将Authlogic设置为我的默认身份验证系统。我希望用户能够使用他们的用户名或电子邮件登录。为此,我做了以下事情:

应用程序/模型/ user.rb:

class User < ActiveRecord::Base

  #add authlogic authentications
  acts_as_authentic do |c|
    c.find_by_login_method :find_by_username_or_email
  end 

  attr_accessible :username, :email, :password, :password_confirmation

  validates :username, :presence => true, 
                       :length => { :within => 3..20 }, 
                       :uniqueness => true, 
                       :format => { :with => /\A[a-z0-9][a-z0-9\-]+[a-z0-9]\z/ }

  validates :email, :presence => true, 
                    :format => { :with => /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i }, 
                    :uniqueness => { :case_sensative => false },
                    :length => { :maximum => 255 }

  validates :password, :presence => true,
                       :confirmation => true,
                       :length => { :within => 6..40 }

  def self.find_by_username_or_email(username_or_email)
    find_by_username(username_or_email) || find_by_email(username_or_email)
  end

end

应用程序/模型/ session.rb:

class Session < Authlogic::Session::Base
end

应用程序/控制器/ sessions_controller.rb:

class SessionsController < ApplicationController
  before_filter :require_no_user, :only => [:new, :create]
  before_filter :require_user, :only => :destroy

  def new
    @session = Session.new
  end

  def create
    username = User.find_by_email(params[:session][:username_or_email]).username
    username ||= params[:session][:username_or_email]
    @session = Session.new(params[:session])

    if @session.save
      flash[:notice] = "Login successful!"
      redirect_back_or_default :users
    else
      render :action => :new
    end
  end

  def destroy
    current_session.destroy
    redirect_back_or_default new_session_url
  end

end

应用程序/视图/会话/ new.html.erb:

<h1>Sign In</h1>

<%= render 'login_form' %>

应用程序/视图/会话/ _login_form.html.erb:

<%= form_for @session do |f| %>
  <div class="field">
    <%= f.label 'Username or Email' %><br />
    <%= f.text_field :login %>
  </div>
  <div class="field">
    <%= f.label :password %><br />
    <%= f.password_field :password %>
  </div>
  <div class="actions">
    <%= f.submit "Sign In", :class => "button" %>
  </div>
<% end %>

配置/ routes.rb中:

Test::Application.routes.draw do

  resources :users
  resources :sessions, :only => :create

  match '/signup', :to => 'users#new'
  match '/signin', :to => 'sessions#new', :as => :signin
  match '/signout', :to => 'sessions#destroy', :as => :signout
end

当我运行rails服务器并尝试连接到http://localhost:3000/signin时,它会出现以下错误:

undefined method `login_field' for Object:Class

完整堆栈跟踪如下:

authlogic (3.0.3) lib/authlogic/session/password.rb:90:in `login_field'
authlogic (3.0.3) lib/authlogic/session/password.rb:213:in `login_field'
authlogic (3.0.3) lib/authlogic/session/password.rb:118:in `initialize'
authlogic (3.0.3) lib/authlogic/session/activation.rb:48:in `initialize'
authlogic (3.0.3) lib/authlogic/session/klass.rb:64:in `initialize'
authlogic (3.0.3) lib/authlogic/session/scopes.rb:79:in `initialize'
authlogic (3.0.3) lib/authlogic/session/persistence.rb:37:in `new'
authlogic (3.0.3) lib/authlogic/session/persistence.rb:37:in `find'
app/controllers/application_controller.rb:15:in `current_session'
app/controllers/application_controller.rb:20:in `current_user'
app/controllers/application_controller.rb:33:in `require_no_user'
activesupport (3.0.7) lib/active_support/callbacks.rb:447:in `_run__2106190539632311804__process_action__1284228636937718599__callbacks'
activesupport (3.0.7) lib/active_support/callbacks.rb:410:in `_run_process_action_callbacks'
activesupport (3.0.7) lib/active_support/callbacks.rb:94:in `run_callbacks'
actionpack (3.0.7) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.0.7) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
activesupport (3.0.7) lib/active_support/notifications.rb:52:in `block in instrument'
activesupport (3.0.7) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.7) lib/active_support/notifications.rb:52:in `instrument'
actionpack (3.0.7) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.0.7) lib/action_controller/metal/rescue.rb:17:in `process_action'
actionpack (3.0.7) lib/abstract_controller/base.rb:119:in `process'
actionpack (3.0.7) lib/abstract_controller/rendering.rb:41:in `process'
actionpack (3.0.7) lib/action_controller/metal.rb:138:in `dispatch'
actionpack (3.0.7) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.0.7) lib/action_controller/metal.rb:178:in `block in action'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:62:in `call'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:62:in `dispatch'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:27:in `call'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:148:in `block in call'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:93:in `block in recognize'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:68:in `optimized_each'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:92:in `recognize'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:139:in `call'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:493:in `call'
sass (3.1.1) lib/sass/plugin/rack.rb:54:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/head.rb:14:in `call'
rack (1.2.2) lib/rack/methodoverride.rb:24:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/flash.rb:182:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/session/abstract_store.rb:149:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/cookies.rb:302:in `call'
activerecord (3.0.7) lib/active_record/query_cache.rb:32:in `block in call'
activerecord (3.0.7) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in `cache'
activerecord (3.0.7) lib/active_record/query_cache.rb:12:in `cache'
activerecord (3.0.7) lib/active_record/query_cache.rb:31:in `call'
activerecord (3.0.7) lib/active_record/connection_adapters/abstract/connection_pool.rb:354:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/callbacks.rb:46:in `block in call'
activesupport (3.0.7) lib/active_support/callbacks.rb:416:in `_run_call_callbacks'
actionpack (3.0.7) lib/action_dispatch/middleware/callbacks.rb:44:in `call'
rack (1.2.2) lib/rack/sendfile.rb:107:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/show_exceptions.rb:47:in `call'
railties (3.0.7) lib/rails/rack/logger.rb:13:in `call'
rack (1.2.2) lib/rack/runtime.rb:17:in `call'
activesupport (3.0.7) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.2.2) lib/rack/lock.rb:11:in `block in call'
<internal:prelude>:10:in `synchronize'
rack (1.2.2) lib/rack/lock.rb:11:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/static.rb:30:in `call'
railties (3.0.7) lib/rails/application.rb:168:in `call'
railties (3.0.7) lib/rails/application.rb:77:in `method_missing'
railties (3.0.7) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.2.2) lib/rack/content_length.rb:13:in `call'
rack (1.2.2) lib/rack/handler/webrick.rb:52:in `service'
/Users/helixed/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/Users/helixed/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/Users/helixed/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'

我真的不明白为什么会这样。如果我使用find_by_login_method,为什么Authlogic甚至需要login_field

更新

我更新了我的代码以匹配Olivier L'的答案。控制器不工作,但我认为它更接近。

应用程序/模型/ user.rb:

class User < ActiveRecord::Base

  #add authlogic authentications
  acts_as_authentic do |c| 
    c.session_class = Session
    c.find_by_login_method :find_by_username_or_email
  end

  attr_accessible :username, :email, :password, :password_confirmation

  validates :username, :presence => true, 
                       :length => { :within => 3..20 }, 
                       :uniqueness => true, 
                       :format => { :with => /\A[a-z0-9][a-z0-9\-]+[a-z0-9]\z/ }

  validates :email, :presence => true, 
                    :format => { :with => /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i }, 
                    :uniqueness => { :case_sensative => false },
                    :length => { :maximum => 255 }

  validates :password, :presence => true,
                       :confirmation => true,
                       :length => { :within => 6..40 }

  def self.find_by_username_or_email(username_or_email)
    find_by_username(username_or_email) || find_by_email(username_or_email)
  end

end

应用程序/模型/ session.rb:

class Session < Authlogic::Session::Base
  authenticate_with User
end

我现在收到错误:

undefined method `find_by_login_method' for #<Class:0x00000101a77ba8>

这是应用程序跟踪:

activerecord (3.0.7) lib/active_record/base.rb:984:in `method_missing'
app/models/user.rb:30:in `block in <class:User>'
authlogic (3.0.3) lib/authlogic/acts_as_authentic/base.rb:36:in `acts_as_authentic'
app/models/user.rb:28:in `<class:User>'
app/models/user.rb:25:in `<top (required)>'
activesupport (3.0.7) lib/active_support/dependencies.rb:454:in `load'
activesupport (3.0.7) lib/active_support/dependencies.rb:454:in `block in load_file'
activesupport (3.0.7) lib/active_support/dependencies.rb:596:in `new_constants_in'
activesupport (3.0.7) lib/active_support/dependencies.rb:453:in `load_file'
activesupport (3.0.7) lib/active_support/dependencies.rb:340:in `require_or_load'
activesupport (3.0.7) lib/active_support/dependencies.rb:491:in `load_missing_constant'
activesupport (3.0.7) lib/active_support/dependencies.rb:183:in `block in const_missing'
activesupport (3.0.7) lib/active_support/dependencies.rb:181:in `each'
activesupport (3.0.7) lib/active_support/dependencies.rb:181:in `const_missing'
activesupport (3.0.7) lib/active_support/dependencies.rb:503:in `load_missing_constant'
activesupport (3.0.7) lib/active_support/dependencies.rb:183:in `block in const_missing'
activesupport (3.0.7) lib/active_support/dependencies.rb:181:in `each'
activesupport (3.0.7) lib/active_support/dependencies.rb:181:in `const_missing'
app/models/session.rb:2:in `<class:Session>'
app/models/session.rb:1:in `<top (required)>'
activesupport (3.0.7) lib/active_support/dependencies.rb:454:in `load'
activesupport (3.0.7) lib/active_support/dependencies.rb:454:in `block in load_file'
activesupport (3.0.7) lib/active_support/dependencies.rb:596:in `new_constants_in'
activesupport (3.0.7) lib/active_support/dependencies.rb:453:in `load_file'
activesupport (3.0.7) lib/active_support/dependencies.rb:340:in `require_or_load'
activesupport (3.0.7) lib/active_support/dependencies.rb:491:in `load_missing_constant'
activesupport (3.0.7) lib/active_support/dependencies.rb:183:in `block in const_missing'
activesupport (3.0.7) lib/active_support/dependencies.rb:181:in `each'
activesupport (3.0.7) lib/active_support/dependencies.rb:181:in `const_missing'
activesupport (3.0.7) lib/active_support/dependencies.rb:503:in `load_missing_constant'
activesupport (3.0.7) lib/active_support/dependencies.rb:183:in `block in const_missing'
activesupport (3.0.7) lib/active_support/dependencies.rb:181:in `each'
activesupport (3.0.7) lib/active_support/dependencies.rb:181:in `const_missing'
app/controllers/application_controller.rb:15:in `current_session'
app/controllers/application_controller.rb:20:in `current_user'
app/controllers/application_controller.rb:33:in `require_no_user'
activesupport (3.0.7) lib/active_support/callbacks.rb:447:in `_run__1226739957950205446__process_action__742106135127651722__callbacks'
activesupport (3.0.7) lib/active_support/callbacks.rb:410:in `_run_process_action_callbacks'
activesupport (3.0.7) lib/active_support/callbacks.rb:94:in `run_callbacks'
actionpack (3.0.7) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.0.7) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
activesupport (3.0.7) lib/active_support/notifications.rb:52:in `block in instrument'
activesupport (3.0.7) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.7) lib/active_support/notifications.rb:52:in `instrument'
actionpack (3.0.7) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.0.7) lib/action_controller/metal/rescue.rb:17:in `process_action'
actionpack (3.0.7) lib/abstract_controller/base.rb:119:in `process'
actionpack (3.0.7) lib/abstract_controller/rendering.rb:41:in `process'
actionpack (3.0.7) lib/action_controller/metal.rb:138:in `dispatch'
actionpack (3.0.7) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.0.7) lib/action_controller/metal.rb:178:in `block in action'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:62:in `call'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:62:in `dispatch'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:27:in `call'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:148:in `block in call'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:93:in `block in recognize'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:68:in `optimized_each'
rack-mount (0.6.14) lib/rack/mount/code_generation.rb:92:in `recognize'
rack-mount (0.6.14) lib/rack/mount/route_set.rb:139:in `call'
actionpack (3.0.7) lib/action_dispatch/routing/route_set.rb:493:in `call'
sass (3.1.1) lib/sass/plugin/rack.rb:54:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/head.rb:14:in `call'
rack (1.2.2) lib/rack/methodoverride.rb:24:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/flash.rb:182:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/session/abstract_store.rb:149:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/cookies.rb:302:in `call'
activerecord (3.0.7) lib/active_record/query_cache.rb:32:in `block in call'
activerecord (3.0.7) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in `cache'
activerecord (3.0.7) lib/active_record/query_cache.rb:12:in `cache'
activerecord (3.0.7) lib/active_record/query_cache.rb:31:in `call'
activerecord (3.0.7) lib/active_record/connection_adapters/abstract/connection_pool.rb:354:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/callbacks.rb:46:in `block in call'
activesupport (3.0.7) lib/active_support/callbacks.rb:416:in `_run_call_callbacks'
actionpack (3.0.7) lib/action_dispatch/middleware/callbacks.rb:44:in `call'
rack (1.2.2) lib/rack/sendfile.rb:107:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/show_exceptions.rb:47:in `call'
railties (3.0.7) lib/rails/rack/logger.rb:13:in `call'
rack (1.2.2) lib/rack/runtime.rb:17:in `call'
activesupport (3.0.7) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.2.2) lib/rack/lock.rb:11:in `block in call'
<internal:prelude>:10:in `synchronize'
rack (1.2.2) lib/rack/lock.rb:11:in `call'
actionpack (3.0.7) lib/action_dispatch/middleware/static.rb:30:in `call'
railties (3.0.7) lib/rails/application.rb:168:in `call'
railties (3.0.7) lib/rails/application.rb:77:in `method_missing'
railties (3.0.7) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.2.2) lib/rack/content_length.rb:13:in `call'
rack (1.2.2) lib/rack/handler/webrick.rb:52:in `service'
/Users/helixed/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:111:in `service'
/Users/helixed/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/httpserver.rb:70:in `run'
/Users/helixed/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/webrick/server.rb:183:in `block in start_thread'

1 个答案:

答案 0 :(得分:1)

编辑:好的,我发现这个other question与你的基本相同。他接受的答案表明你需要这样做:

class Session < Authlogic::Session::Base
  authenticate_with User
end


class User < ActiveRecord::Base
  acts_as_authentic do |c| 
    c.session_class = Session
    c.find_by_login_method :find_by_username_or_email
  end
end

查看here以获得实现多登录字段身份验证的好方法。


以防万一链接破坏,这就是Michael Cindric在他的博客中建议的内容(编辑后使用你的类和字段名称):

class Session < Authlogic::Session::Base
  find_by_login_method :find_by_username_or_email
end

class User < ActiveRecord::Base
  def self.find_by_username_or_email(login)
    find_by_username(login) || find_by_email(login)
  end
end