views:

71

answers:

2

I have a Post model object that has reference to a parent object. The edit, new and reply methods all use the same partial template.

The posts_controller methods:

def edit
  @post = Post.find(params[:id])
end

def reply
  @post = Post.new
  @replypost = Post.find(params[:id])
  @post.title = @replypost.title
  @post.parent = @replypost
end

The partial template code:

<% form_for(@post) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :body %><br />
    <%= f.text_area :body %>
  </p>
  <%= if :parent then f.hidden_field :parent end %>
  <p>
    <%= f.submit "Create" %>
  </p>
<% end %>

If I look at the source HTML generated by the partial template, I can see that I'm passing some sort of object id to my create method.

<input id="post_parent" name="post[parent]" type="hidden" value="#&lt;Post:0x103e3bdf0&gt;" />

The problem is that when I try and save this new object I've created, I get a warning that it was expecting a Post and got a String. I'm sure that I can work around this by setting and getting the parent_id and passing that with my form, but I'm wondering if there isn't a better way to do this, something more elegant and Rails-esque.

+3  A: 

try <%= f.hidden_field :parent_id unless @post.parent.nil? %>

This will pass the parent id with the post and you can then .find(params[:post][:parent_id]) if you need the object later.

Question Mark
perfect. Thanks!
kubi
bare in mind that using the UNLESS (or the IF in your question) will result in the hidden field not being created at all sometimes, so params[:post][:parent_id] could be null
Question Mark
+1  A: 

From what it looks like,

<%= if :parent then f.hidden_field :parent end %>

isn't able to infer that when you say :parent, you want the value of the hidden field to be the parent post's ID.

You have to explicitly use the :parent_id to generate the hidden field's value because it can't be inferred as it can elsewhere in Rails.

Blaine LaFreniere