2

我有一个名为 的模型Book,我想调整标准Book#new以显示 10 本书的字段,这样就可以一次创建 10 本书,而不仅仅是一本。

我查看了这个问题,发现如果我添加10.times到我的表单中,我可以重复该表单。但是,我没有正确执行此操作,因为保存了一条新记录,但所有字段均为空。

我想做的是:

  1. 允许用户一次输入最多 10 本书然后保存
  2. 如果用户只填充了三个书籍记录,则只创建三个(并忽略其他具有空值的表单中的七个记录)

我的观点:

<%= simple_form_for(@book) do |f| %>
  <%= f.error_notification %>
  <% 10.times do |index|%>
    <%= f.input :title %>
    <%= f.association :book_category %>   
  <% end %>

  <%= f.submit %>
<% end %>

我的控制器与脚手架代码没有变化:

def new
  @book = Book.new
end

def create
  @book = Book.new(params[:book])
end
4

2 回答 2

12

您不能使用与帖子中其他问题相同的方法的原因是 bc @book 不是用户的嵌套属性。您只是为一本新书创建一个表单,因此控制器中没有任何特殊内容,rails 只会保存一本书。一种选择是使书籍成为用户的嵌套属性,以便您可以一次创建多本书。以下是您需要如何设置模型和表单来处理嵌套属性。

Class User < ActiveRecord::Base
  has_many :books
  accepts_nested_attributes_for :books, :reject_if => lambda { |b| b[:title].blank? }
  attr_accessible :books_attributes
end 

Class Book < ActiveRecord::Base
  belongs_to :user
end

reject_if忽略任何提交给控制器但没有标题的记录。您会想要这个,因为您假设许多用户不会使用所有 10 个字段。下面是你的表格。

<%= form_for @user do |f| %>
  <%= f.fields_for :books, [Book.new]*10 do |book| %>
    <%= book.text_field :title %>
    <%= book.association :book_category %>
  <% end %>
  <%= f.submit %>
<% end %>

重要的是要注意这个表单将被提交给用户控制器,因为它是一个用户表单。用户控制器将像处理用户的任何其他属性一样处理创建/更新所有书籍,因为书籍现在被接受为嵌套属性。有关更多示例,请查看有关嵌套属性的Railscast 。

正如我上面提到的,这只是一种选择。如果您不想让 book 成为用户的嵌套属性,那么另一种选择是生成 10 组 book 输入字段,就像您已经在做的那样,然后在 Books 控制器的 create 操作中分解 params 哈希。通过这样做,您可以遍历散列并为每组输入创建一本书。这比使用更“hacky”,accepts_nested_attributes_for但它是另一种选择,所以我想我会提到它。

于 2013-03-09T00:54:42.957 回答
2

您引用的示例文章正在讨论嵌套模型表单。Railscasts 在这里也有一个视频:http ://railscasts.com/episodes/196-nested-model-form-part-1

两者都指与其他模型有关系的模型的单个实例。

您想要做的是同一模型的多个实例,而不是嵌套关系。

我的问题是,为什么?他们真的节省了从一个字段集到另一个字段集的时间,而不是按 Enter 提交单个记录吗?

如果您想节省数据输入的时间,为什么不将create操作重定向回新的,以便他们可以立即输入下一条记录?还是在每条记录提交后使用 AJAX 向页面添加一个新的字段集?

我认为这些方法将使您的视图和控制器保持良好和 RESTful。

于 2013-03-08T22:53:05.683 回答