所以我正在使用authlogic,我正在尝试将登录功能复制到欢迎页面,以便您可以通过restful url或只是转到主页面登录。不,我不知道我们是否会保留这个功能,但无论如何我想测试一下。这是错误消息:
RuntimeError in Welcome#index
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
代码如下。基本上,正在发生的是索引视图(第一个代码片段)将信息从表单发送到user_sessions控制器的create方法。在这一点上,从理论上讲,创造它应该只是提升,但事实并非如此。
请帮忙。请。我已经这样做了大约8个小时。我查了一下Google。我检查了IRC。我检查了我能找到的每本书。你甚至不必回答,如果你只是指出我正确的方向,我可以做咕噜咕噜的工作。
Sameera足以提供问题的答案。打开问题,但是组织应用程序的最佳方式是什么。将对象@user_sessions应用于可接受的before_filter中,还是有更多的rails-y方式来执行此操作?
欢迎#INDEX
<% form_for @user_session, :url => user_sessions_path do |f| %>
<%= f.text_field :email %><br />
<%= f.password_field :password %>
<%= submit_tag 'Login' %>
<% end %>
应用程序控制器
class ApplicationController < ActionController::Base
helper :all # include all helpers, all the time
protect_from_forgery # See ActionController::RequestForgeryProtection for details
# Scrub sensitive parameters from your log
# filter_parameter_logging :password
helper_method :current_user_session, :current_user
before_filter :new_session_object
protected
def new_session_object
unless current_user
@user_session = UserSession.new(params[:user_session])
end
end
private
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session && current_user_session.record
end
end<pre></code>
用户会话控制器
class UserSessionsController < ApplicationController
def new
@user_session = UserSession.new
end
def create
@user_session = UserSession.new(params[:user_session])
if @user_session.save
flash[:notice] = "Logged in"
redirect_to root_url
else
render :controller => 'user_sessions', :action => 'new'
end
end
def destroy
@user_session = UserSession.find
@user_session.destroy
flash[:notice] = "Logged out"
redirect_to root_url
end
end
更详细的STACK TRACE
1: <h1>Welcome#index</h1>
2: <p>Find me in app/views/welcome/index.html.erb</p>
3:
4: <% form_for @user_session, :url => user_sessions_path do |f| %>
5: <%= f.text_field :email %><br />
6: <%= f.password_field :password %>
7: <%= submit_tag 'Login' %>
Application Trace | Framework Trace | Full Trace
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpac -2.3.5/lib/action_controller/record_identifier.rb:76:in `dom_id'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/record_identification_helper.rb:16:in `dom_id'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:293:in `apply_form_for_options!'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:277:in `form_for'
/Users/alex/Desktop/anglic/app/views/welcome/index.html.erb:4:in `_run_erb_app47views47welcome47index46html46erb'
答案 0 :(得分:1)
您应该将以下方法添加到ApplicationController:
def require_user
unless current_user
flash[:notice] = "You must be logged in to access this page!"
redirect_to :controller => "user_sessions", :action => "new"
return false
end
end
然后在WelcomeController中添加一个像这样的前置过滤器:
before_filter :require_user
现在,访问WelcomeController的任何人都将被重定向到登录页面。您不必跨控制器复制功能。
请仔细阅读Authlogic设置教程:http://rdoc.info/projects/binarylogic/authlogic
答案 1 :(得分:0)
我认为你可以在WelcomeController中试试这个
class WelcomeController < ActionController::Base
def index
@user_session = UserSession.new
.....
end
.....
end
在我看来,您正在尝试使用未在WelcomeController索引操作视图中定义的@user_session。
希望它有所帮助。
编辑#1
在我看来,在WelcomeController #index操作中提交表单后调用before_filter时会出现问题。
这段特殊代码对我来说很奇怪
class ApplicationController < ActionController::Base
.....
private
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
.....
end
我很确定UserSession.find
会破裂。
希望这个编辑有所帮助。
编辑#2
我发现奇怪的另一件事是在受保护的方法new_session_object中:
protected
def new_session_object
unless current_user
@user_session = UserSession.new(params[:user_session])
end
end
使用UserSession.new
创建params[:user_session]
的原因是什么?
根据我的理解,您UserSessionController
登录的流程是:
before_filter
:new_session_object
被称为
它将返回false
current_user
因为它是新的
用户会话
它会设置@user_session
变量
至
UserSession.new(params[:user_session])
值
UserSessionController#new
行动
被称为覆盖
@user_session
变量
UserSession.new
new.html.erb
已呈现
包含登录表格
before_filter :new_session_object
is
再次致电
它将返回false
current_user
因为它仍然是一个
新用户会话
它会设置@user_session
变量
至
UserSession.new(params[:user_session])
值
UserSessionController#create
再次召唤行动
将@user_session
变量设置为
UserSession.new(params[:user_session])
值。
@user_session
已保存并且已保存
用户会话成功
创建
但对于WelcomeController
,它在步骤4中略有不同
@user_session
中使用的WelcomeController#index
变量值来自before_filter
的{{1}}调用变量赋值,此时UserSession.new(params[:user_session])
值为params[:user_session]
,因此nil
呈现@user_session = UserSession.new(nil)
。
我不完全确定这是否会导致您的问题,但如果您运行ndex.html.erb
并在使用{script/server --debugger
时创建@user_session
,则可能会帮助您解决此问题1}},特别是当表单发布到WelcomeController
时。
答案 2 :(得分:0)
试试这个:
form_for :user_session, @user_session, :url => user_session_path(@user_session)} do |f|
end