我有一个Post
模型对象,它引用了父对象。 edit
,new
和reply
方法都使用相同的部分模板。
posts_controller
方法:
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
部分模板代码:
<% 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 %>
如果我查看部分模板生成的源HTML,我可以看到我将某种对象id传递给我的create方法。
<input id="post_parent" name="post[parent]" type="hidden" value="#<Post:0x103e3bdf0>" />
问题在于,当我尝试保存这个我创建的新对象时,我得到一个警告,它期待一个Post并得到一个String。我确信我可以通过设置和获取parent_id并将其传递给我的表单来解决这个问题,但我想知道是否有更好的方法来做到这一点,更优雅和Rails-esque。
答案 0 :(得分:5)
尝试<%= f.hidden_field :parent_id unless @post.parent.nil? %>
这将使用帖子传递父ID,然后如果您以后需要该对象,则可以.find(params[:post][:parent_id])
。
答案 1 :(得分:2)
对于想要发送对象而不是id的人(当你有未保存的对象时很有用),你可以执行以下操作:
在您看来:
<% form_for(@post) do |f| %>
...
<%= hidden_field_tag :param_name, @object.to_param %>
在您的控制器中:
object = Rack::Utils.parse_nested_query params[:param_name]
适用于嵌套哈希。尚未使用阵列或阵列哈希进行测试。
我在跨多个视图构建对象时发现这是必要的,如果我之前尝试保存,则无法通过验证。
警告:hidden_field_tag
中的用户可以看到@object中的数据。他们只需要点击“查看来源”即可。仔细考虑使用此方法序列化的任何对象。
答案 2 :(得分:1)
从它看起来像,
<%= if :parent then f.hidden_field :parent end %>
无法推断当你说:parent时,你希望隐藏字段的值是父帖子的ID。
你必须明确地使用:parent_id来生成隐藏字段的值,因为它不能像在Rails中的其他地方那样被推断。