Ruby on rails 运行时错误-在Rails 3项目中为nil调用id

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

当我尝试提交表单(/POSTS/SHOW)时出现此错误:

应用程序控制器(这是我定义当前用户的地方)

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 %>