Rails:需要帮助在另一个模型的视图中显示一个模型的表单

Posted

技术标签:

【中文标题】Rails:需要帮助在另一个模型的视图中显示一个模型的表单【英文标题】:Rails: need help displaying a form_for one model in the view of another model 【发布时间】:2011-05-07 16:26:21 【问题描述】:

我有两个模型,字符和统计。它们的关系是 Character has_one Statistic 和 Statistic belongs_to Character。

我已经为这两个模型生成了脚手架,我想要做的是能够创建一个新的 Statistic(如果没有),显示 Statistic 模型并编辑 Statistic 模型,所有这些都来自 Character 视图。我不确定如何编辑控制器或在视图中编写代码来实现这一点。

这里有一些代码。从角色视图:

<h2>Statistics</h2>
<%= render "statistics/form" %>

但是,这给了我这个错误:

undefined method `build' for nil:NilClass
Extracted source (around line #1):

1: <%= form_for ([@character, @character.statistic.build]) do |f| %>
2:   <% if @statistic.errors.any? %>
3:     <div id="error_explanation">
4:       <h2><%= pluralize(@statistic.errors.count, "error") %> prohibited this statistic from being saved:</h2>

所以我假设我没有正确写出第一行?我认为这会起作用,因为我希望 Statistic 的每个实例都属于一个角色,这会创建这种关系。

这是来自统计/表格的代码:

<%= form_for ([@character, @character.statistic.build]) do |f| %>
<% if @statistic.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@statistic.errors.count, "error") %> prohibited this statistic from                 
being saved:</h2>

<ul>
<% @statistic.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="field">
<%= f.label :strength %><br />
<%= f.text_field :strength %>
...
<div class="field">
<%= f.label :charisma %><br />
<%= f.text_field :charisma %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

提前感谢您的帮助。大约一个星期以来,我一直在努力以这种方式关联模型,但我很沮丧,因为我仍然不理解。

【问题讨论】:

【参考方案1】:

您可以在角色表单中包含统计字段并自动创建关联,但过程不同。

首先在您的Character 模型中使用accepts_nested_attributes_for:

has_one :statistic
accepts_nested_attributes_for :statistic

并在你的角色形式中使用fields_for:

<%= form_for @character do |f| %>

  ... all your character fields as generated in your scaffold

  <%= f.fields_for :statistic do |statistic_fields| %>
    ... all your statistic fields using statistic_fields as form object, ie:
    <%= statistic_fields.label :strength %><br />
    <%= statistic_fields.text_field :strength %>
    ...
  <% end %>
  <%= f.submit %>
<% end %>

编辑:如果要分隔表单,您仍然可以使用部分:

将统计形式改为如下形式:

<%= form_for @statistics do |f| %>
  <%= render :partial => "statistics/fields", locals => :f => f %>
<% end %>

创建一个统计字段部分app/views/statistic/_fields.html.erb,其中包含之前在上述表单中的所有字段:

<div class="field">
<%= f.label :strength %><br />
<%= f.text_field :strength %>
...

然后你可以像这样在你的字符表单中重用统计字段:

<%= form_for @character do |f| %>
  ...
  <%= f.fields_for :statistic do |statistic_fields| %>
    <%= render :partial => "statistics/fields", locals => :f => statistic_fields %>
  <% end %>
  <%= f.submit %>
<% end %>

【讨论】:

嗯,我不认为这正是我正在寻找的。我要做的是理顺 Character 和 Statistic 之间的这一关系,然后使用该代码关联未来的模型。每个角色还会有技能、专长、装备等,所以我不想将所有内容都加载到角色表单中。是否可以在 Character 视图上显示 Statistic 模型,然后有一个链接来编辑将反映在 Character 视图上的 Statistic?我需要为此创建一个新的 html.erb 文件到 link_to 吗? 我不确定我是否理解您的目标。在为这些东西生成脚手架之后,是否要尽量减少工作?或者您是否希望能够以自己的形式编辑统计信息(和其他)?我编辑了答案,向您展示了一种方法。 其实我都想要。我绝对想要一种以自己的形式编辑统计信息等的方法,并且我想将这些代码分开,这样字符视图就不会太混乱。您发布的新方法听起来可能会奏效,所以我会试一试。谢谢!【参考方案2】:

has_one 关系的 Build 和 create 调用与 has_many 不同。

使用 has_many @character.statistic.build 有效,但使用 has_one,需要这样做:

@character.build_statistic 和 .create_statistic

我创建了一个应用程序来测试它,并为你把它扔到了 Github 上。希望对你有帮助。

https://github.com/unixmonkey/Manticore_example

【讨论】:

以上是关于Rails:需要帮助在另一个模型的视图中显示一个模型的表单的主要内容,如果未能解决你的问题,请参考以下文章

Rails 4 - 如何获得 <li> 单击以在另一个 <div> 中显示部分视图?

Rails 3 - 在另一个帖子的SHOW视图中无法创建新帖子

Rails,在视图中显示模型的名称而不是 id

Rails - 一个视图中有 2 个模型(属于另一个模型的模型)

优化重复 Rails 代码的正确方法

在另一个模型控制器中使用的 Rails 3 虚拟属性