“Couldn't find <object> without an ID”

末鹿安然 提交于 2020-07-05 09:58:12

问题


I'm having problems implementing a kind of comments form, where comments (called "microposts") belong_to both users and posts, users have_many comments, and posts (called "propositions") have_many comments.

My code for the comments form is:

<%= form_for @micropost do |f| %>
  <div class="field">
      <%= f.text_area :content %>
  </div>

  <div class="actions">
    <%= f.submit "Submit" %>
  </div>
<% end %>

The MicropostsController has this in the create action:

  def create

      @proposition = Proposition.find(params[:proposition_id])

  @micropost = current_user.microposts.build(params[:micropost])
  @micropost.proposition = @proposition
  if @micropost.save
      flash[:success] = "Contribution submitted"
      redirect_to root_path
  else
          @feed_items = []    
      render 'pages/home'
  end
  end

The form for creating a new micropost is on the same page as a proposition, yet the proposition id doesn't seem to get passed at any point.

This is the error I get on submitting the micropost form:

ActiveRecord::RecordNotFound in MicropostsController#create

Couldn't find Proposition without an ID

Parameters are:

{"commit"=>"Submit", "micropost"=>{"proposition_id"=>"", "content"=>"First comment"}, "authenticity_token"=>"TD6kZaHv3CPWM7xLzibEbaLJHI0Uw43H+pq88HLZFjc=", "utf8"=>"✓"}

I'm completely new to rails and very new to coding anything at all, so I'd be grateful for any help you can give me!

Thanks in advance.


回答1:


Your params are:

"micropost"=>{"proposition_id"=>"", "content"=>"First comment"}

So to get proposition_id, you have to do :

params[:micropost][:proposition_id]

But this is empty. And there is nowhere else to get this id, that's why this line retrieves nil:

@proposition = Proposition.find(params[:proposition_id])

Making this fail:

@micropost.proposition = @proposition

You must either:

  • add the proposition_id as an hidden_field

  • store it in session

But I don't know your context enough to give you the proper solution here.

EDIT:

In your link, replace:

<%= f.hidden_field :proposition_id %>

with:

<%= f.hidden_field :proposition_id, :value => @proposition.id %>

If it doesn't work, show your params.

Note: it's bad practice to rely on instance variables, you should send local variable to each partial




回答2:


As you can see, the proposition_id parameter is empty, so your controller can't find the proposition unless you give it a valid id.

You need to make sure your new form sends the proposition_id attribute. One way to do this is:

  1. Set the proposition in the new action in the controller: @micropost.proposition = ...

  2. In the form, add a hidden field for the id: f.hidden_field :proposition_id

  3. In the create action, find the appropriate Proposition with params[:micropost][:proposition_id]

(You'll also want to make sure to use attr_accessible in your Micropost model, and make sure proposition_id is NOT in that list. Otherwise, you'll be open to nasty security holes. See http://www.kalzumeus.com/2010/09/22/security-lessons-learned-from-the-diaspora-launch/ and Which fields should be protected from mass assignment?)

EDIT (due to comment):

Your new action should be like this:

def new
  @micropost = Micropost.new
  @micropost.proposition_id = params[:proposition_id]

This is slightly different from what is said above, and is due to the fact you're sending the proposition id in the request to new. There's no need to look up the actual proposition record, since we're only interested in the id field (which we already have).



来源:https://stackoverflow.com/questions/6215533/couldnt-find-object-without-an-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!