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

时间:2012-04-23 09:41:02

标签: ruby-on-rails ruby-on-rails-3 forms

当我尝试提交表单(/ POSTS / SHOW)时,我收到此错误:

RuntimeError in Posts#show

Showing /Users/fkhalid2008/loand/app/views/posts/show.html.erb where line #1 raised:

Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Extracted source (around line #1):

1: <%= form_remote_tag (:update => 'message', :url => {:controller => 'main', :action => 'send_message', :user_id => @post.user.id}) do %>
2: <br>
3: <br />
4: <br />

我该如何解决这个问题?

相关代码如下:

/视图/帖子/ SHOW

<%= form_remote_tag (:update => 'message', :url => {:controller => 'main', :action => 'send_message', :user_id => @post.user.id}) do %>
<br>
<br />
<br />
<div class="field">

您好!我的名字是&lt;%= f.text_field:subject%&gt;我正在与您联系以回复您的广告。我有兴趣学习更多,所以请联系!这是我的联系方式:&lt;%= f.text_field:body%&gt;。          提交     &lt;%end%&gt;

POST MODEL

class Post < ActiveRecord::Base

belongs_to :user

attr_accessible :title, :job, :location, :salary

validates :title, :job, :location, :salary, :presence => true 
validates :salary, :numericality => {:greater_than_or_equal_to => 1} 

default_scope :order => 'posts.created_at DESC'
end

用户模型

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

POSTS CONTROLLER

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 

APPLICATION CONTROLLER(这是我定义current_user的地方)

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

MAIN CONTROLLER(此处定义send_message)

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

2 个答案:

答案 0 :(得分:1)

您收到错误是因为@post.user中的nil:user_id => @post.user.id

确保在帖子控制器的show动作中定义@post,并且它具有有效的用户关联。

答案 1 :(得分:1)

您没有将用户分配给@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来解释登录和退出以及重定向前过滤器http://railscasts.com/episodes/250-authentication-from-scratch

此处有一个修改后的演员版,但您需要订阅 http://railscasts.com/episodes/250-authentication-from-scratch-revised

非常值得为IMO支付

更新结束

您将需要/还应该为当前用户分配更新帖子记录的任何操作 - 即创建和更新操作完全相同。

此外,由于您没有将用户分配到帖子记录,因此您需要在表单中处理此方案,以便您不会收到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 %>