Ruby on rails 运行时错误-在Rails 3项目中为nil调用id
当我尝试提交表单(/POSTS/SHOW)时出现此错误: 应用程序控制器(这是我定义当前用户的地方)Ruby on rails 运行时错误-在Rails 3项目中为nil调用id,ruby-on-rails,ruby-on-rails-3,forms,Ruby On Rails,Ruby On Rails 3,Forms,当我尝试提交表单(/POSTS/SHOW)时出现此错误: 应用程序控制器(这是我定义当前用户的地方) class ApplicationController@post.user.id中为nil 确保您在post控制器的show action中定义了@post,并且它具有有效的用户关联。您没有为@post实例变量表示的post记录分配用户 假设用户需要登录才能发布帖子? 您可能在某个地方定义了当前用户 使用此表单的控制器操作需要将用户分配给post记录 def new @post = Post
class ApplicationController
主控制器(此处定义了发送消息)
class MainController“嗯,好像出了什么问题……让我调查一下”
结束
结束
您收到错误是因为@post.user
在:user\u id=>@post.user.id
中为nil
确保您在post控制器的show action中定义了
@post
,并且它具有有效的用户关联。您没有为@post实例变量表示的post记录分配用户
假设用户需要登录才能发布帖子?
您可能在某个地方定义了当前用户
使用此表单的控制器操作需要将用户分配给post记录
def new
@post = Post.new
@post.user = current_user # You will need to get the current user from somewhere
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @post }
end
end
更新
为确保已分配当前用户,您应添加一项检查,以确保该用户已登录控制器操作。这通常是通过添加一个before过滤器来授权当前用户,如果当前用户注销,该过滤器将重定向回登录页面。
看一下这个rails cast,解释在before过滤器上登录、注销和重定向
这里有一个修订版的演员阵容,但你需要订阅
很值得为IMO付款
更新结束
class MainController < ApplicationController
def send_message
message = Message.new
message.subject = params[:subject]
message.body = params[:message]
message.sender = User.find session[:user]
message.recipient = User.find params[:user_id]
if message.save
ContactMailer.deliver_message_email message.recipient.email, message.id, request.host
return redirect_to "/posts"
else
render :text => "Hmm. Something seems to be wrong...let me look into it"
end
end
您还需要/应该在更新post记录的任何操作中分配当前用户,即以完全相同的方式创建和更新操作
另外,由于您没有将用户分配给post记录,因此您需要在表单中处理此场景,以避免出现500个错误
您可以使用@post.user.blank?布尔检查可帮助您完成此操作
差不多
<% if @post.user.blank? %>
<h2>There is no user assigned to this post record! This should never happen ad you should never see this message, please contact support if etc... </h2>
<% else %>
<!-- Place all your current form code here -->
<% end %>
没有分配给此日志记录的用户!这不应该发生广告你不应该看到这条消息,请联系支持,如果等。。。
您是否在帖子的控制器show action中定义了@post?否(请参见上面添加的控制器)。我需要添加什么来修复此问题?是的,您有(@post=post.find(params[:id])
)顺便说一下:nil的对象id始终为4,而不是任何其他值。@post=post.find(params[:id])
通常是可以的。在控制台中进行一些测试:post=post.find(id)
&post.user
我已经用您提供的代码定义了edit-post方法(请参见上面的控制器)…仍然收到相同的错误我没有提供任何代码或谈论编辑。用rails c打开控制台,检查这两个命令的输出。在rails控制台中,我得到post=post.user的‘nil’。(对于post=post.find(1)我得到了一个有效的条目..所以问题是@post没有关联的用户记录。现在,通过查看PostController的创建操作可以明显看出这一点。在保存@post之前,您需要像@post.user=current\u user
这样的内容。您所说的@post都做了(除了布尔检查)但是对于post.user仍然得到相同的错误/“nil”!!我做错了什么?更新的代码附在上面您需要添加布尔检查。您得到错误是因为您分配的当前用户没有设置为任何值。我将更新我的回答谢谢-刚刚看到您发布的rails cast详细信息,我想这是针对authenti的有用户登录和注销的阳离子系统。但这不是我想要的。我想要的是更类似于此的东西:。即,没有密码或用户名的用户身份验证。要尝试复制链接中描述的内容,让我们看看它是否有效!您的逻辑与您的要求相矛盾。启动一个新的聊天室并邀请我n如果你想说清楚的话。你链接到的系统不起作用,原因很多,海报没有解释。
class User < ActiveRecord::Base
has_many :posts
has_one :profile
has_private_messages
attr_accessible :email
validates_presence_of :email
validates_uniqueness_of :email, :message =>"Hmm, that email's already taken"
validates_format_of :email, :with => /^([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})$/i, :message => "Hi! Please use a valid email"
end
def show
@post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @post }
end
end
def new
@post = Post.new
@post.user = current_user
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @post }
end
end
def edit
@post = Post.find(params[:id])
end
def create
@post = Post.new(params[:post])
@post.user = current_user
respond_to do |format|
if verify_recaptcha && @post.save
format.html { redirect_to :action=> "index"}
format.json { render :json => @post, :status => :created, :location => @post }
else
format.html { render :action => "new" }
format.json { render :json => @post.errors, :status => :unprocessable_entity }
end
end
end
def update
@post = Post.find(params[:id])
@post.user = current_user
respond_to do |format|
if @post.update_attributes(params[:post])
format.html { redirect_to @post, :notice => 'Post was successfully updated.' }
format.json { head :ok }
else
format.html { render :action => "edit" }
format.json { render :json => @post.errors, :status => :unprocessable_entity }
end
end
end
class ApplicationController < ActionController::Base
protect_from_forgery
private
def current_user
@_current_user ||= session[:current_user_id] &&
User.find_by_id(session[:current_user_id])
end
end
class MainController < ApplicationController
def send_message
message = Message.new
message.subject = params[:subject]
message.body = params[:message]
message.sender = User.find session[:user]
message.recipient = User.find params[:user_id]
if message.save
ContactMailer.deliver_message_email message.recipient.email, message.id, request.host
return redirect_to "/posts"
else
render :text => "Hmm. Something seems to be wrong...let me look into it"
end
end
def new
@post = Post.new
@post.user = current_user # You will need to get the current user from somewhere
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @post }
end
end
<% if @post.user.blank? %>
<h2>There is no user assigned to this post record! This should never happen ad you should never see this message, please contact support if etc... </h2>
<% else %>
<!-- Place all your current form code here -->
<% end %>