Rails。 Has_many :through 和 form_for 复选框字段的参数

Rails. Has_many :through and form_for params for a checkbox field

所以我有这样的联想:

class FirstModel 
 has_many :merged_models
 has_many :second_models, :through => :merged_models
end

class SecondModel 
 has_many :merged_models
 has_many :first_models, :through => :merged_models
end

class MergedModel 
 belongs_to :first_model
 belongs_to :second_model
end

现在我的问题是理解这个帮助 check_box_tag 助手从我的表单中传递的集合中识别 HTML 中的元素的技巧:

form_for(first_model) do |f|

  <% SecondModel.all.each do |s| -%>
    <div>
      <%= check_box_tag 'second_model_ids[]', s.id, first_model.second_models.include?(s), :name => 'first_model[second_model_ids][]'-%>
      <%= label_tag :second_model_ids, s.first_name -%>
    </div>
  <% end -%>

我不明白的是:

first_model.second_models.include?(s), :name => 'first_model[second_model_ids][]'

我认为:

first_model.second_models.include?(s)

检查 SecondModel 的对象 ID 是否已经在 FirstModel 的 second_model_ids 数组中。在这种情况下,我会期待类似 if 语句的东西 - 如果这个 id 存在,那么就这样做,等等

这部分让我更加困惑:

:name => 'first_model[second_model_ids][]'

:name 是从哪里来的?为什么 first_model[second_model_ids][] 有两个方括号 - 它们在 Rails 语法中是如何工作的?要将这个新检查的 id 合并到 second_model_ids 数组?

我会感谢所有信息。谢谢!

所以 check_box_tag 有这个签名:

check_box_tag(name, value = "1", checked = false, options = {})

你的情况:

check_box_tag 'second_model_ids[]', s.id, first_model.second_models.include?(s), :name => 'first_model[second_model_ids][]'

第一个参数(名称)是'second_model_ids[]',这将用作标签的id=部分。 复选框的第二个参数(值)是 s(SecondModel 的当前实例)的 id。 第三个参数(勾选)是:

first_model.second_models.include?(s)

你的意思是对的,你不需要'if'。 include?() returns 一个布尔值(就像大多数以问号结尾的 Ruby 方法一样)。您可以在 irb 或 rails 控制台中尝试此操作:

[1,2,3].include?(2)
# => true

最终选项:

:name => 'first_model[second_model_ids][]'

传递选项的散列,将用作 html。在这种情况下,带有键的单个散列值 :name (不要与上面的第一个参数混淆,它在 html 标记中用作 id='...'),这将被直接使用在标签中作为

name='first_model[second_model_ids][]'

你对这里的语法也是正确的。括号帮助 Rails 将其解析为带有

的参数散列的正确嵌套
first_model: {foo: 1, bar: 2, second_model: {some: stuff, other: stuff}}