我有一个模型A,它可以在一对多关系中拥有多达10个关联模型B.这些嵌套模型只有一个表示单词的字符串属性。
我想显示一个表单来创建/编辑父模型和所有嵌套子项,显示10个可能模型的字段。然后,如果我只填写其中两个,将创建两个模型。
最后,在编辑模型A时,我需要显示10个字段,其中两个填充了与A数据关联的模型B,其余的空白准备填充。
使用数组尝试fields_for
,但它只显示已存在的模型B实例的字段。
查看:
= form_for @a, remote: true do |f|
= f.text_field :title, placeholder: true
= f.fields_for :bs, @a.bs do |ff|
/ Here, for the edit action, N text fields appear, being N equals to @soup.soup_words.size
/ and I need to display 10 fields everytime, because a Soup can have up to 10 SoupWord
/ For the new action, it should display 10 empty text fields.
/ Finally, if you fill three of the 10 fields,
/ model A should have only 3 instances of model B associated. i.e if there were 4 filled and
/ I set one of them blank, the model B instance should be destroyed.
= ff.text_field :word, placeholder: true
= f.submit
控制器:
class Bs < ApplicationController
def edit
respond_to :js
@soup = Soup.find params[:id]
end
def update
respond_to :js
puts params
end
end
更新
现在可以创建和编辑操作,只需在模型A中添加reject_if
参数,
accepts_nested_attributes_for :bs, reject_if: proc { |attrs| attrs[:word].blank? }
并在控制器上设置build
。
def new
respond_to :js
@a = A.new
10.times { @a.bs.build }
end
def edit
respond_to :js
@a = Soup.find params[:id]
@a.bs.size.upto(9) do |sw|
@a.bs.build
end
end
现在我需要销毁模型B的实例,如果我在编辑操作中将它们设置为空白。
答案 0 :(得分:1)
通常,您可以使用allow_destroy: true
选项并传递_destroy
参数来删除嵌套记录:
class Soup
accepts_nested_attributes_for :soup_words,
reject_if: proc { |attrs| attrs[:word].blank? },
allow_destroy: true
end
要获得您想要的行为,您可以使用带有隐藏输入的javascript:
= form_for @soup, remote: true do |f|
= f.text_field :title, placeholder: true
= f.fields_for :soup_words, @soup.soup_words do |ff|
= ff.text_field :word, class: 'soup_word', placeholder: true
= ff.hidden_input :_destroy
= f.submit
$(document).on('change', '.soup_word', function(){
var $obj = $(this);
if (!this.value || !this.value.length) {
// set soup_word to be destroyed
$obj.siblings('input[name~=_destroy]').val('1');
}
$obj.fadeOut(50);
});
确保您已将_destroy
和id
参数列入白名单。
def update_params
params.require(:soup).permit(:soup_words_attributes: [:word, :id, :_destroy])
end