当我向collection_select添加“multiple true”时,Rails 4 HABTM停止工作

时间:2013-12-03 07:24:09

标签: ruby-on-rails ruby

我在谷歌搜索并尝试了过去几天我能想到的所有事情来解决has_and_belongs_to_many关系中一个相对简单(我推测)的问题。

我设法成功使用HABTM关系来提交单个关系值。这是示例代码:

型号:

class Livre < ActiveRecord::Base
  has_and_belongs_to_many : auteurs
end

class Auteur < ActiveRecord::Base
  has_and_belongs_to_many :livres
end

控制器:

def new
  @livre = Livre.new
  @auteurs = Auteur.all
end

def create
  @livre = Livre.new(livre_params)
  if @livre.save
    redirect_to [:admin, @livre]
  else
    render 'new'
  end
end

private
  def livre_params
    params.require(:livre).permit(:name, :auteur_ids)
  end

查看:

<% f.label :auteur %><br>
<% f.collection_select(:auteur_ids, @auteurs, :id, :name) %>

发表参数:

{"utf8"=>"✓",
 "authenticity_token"=>"mAXUm7MRDgJgCH00VPb9bpgC+y/iOfxBjXSazcthWYs=",
 "livre"=>{"name"=>"sdfsdfd",
 "auteur_ids"=>"3"},
 "commit"=>"Create Livre"}

但是当我尝试将“multiple true”添加到视图的collection_select帮助器时,(现在多个)关系不再被保存。示例代码:

(模型和控制器均未更改)

查看:

<% f.label :auteur %><br>
<% f.collection_select(:auteur_ids, @auteurs, :id, :name, {}, {:multiple => true}) %>

发表参数:

{"utf8"=>"✓",
 "authenticity_token"=>"mAXUm7MRDgJgCH00VPb9bpgC+y/iOfxBjXSazcthWYs=",
 "livre"=>{"name"=>"sdfsdf",
 "auteur_ids"=>["1",
 "5",
 "3"]},
 "commit"=>"Create Livre"}

如您所见,“auteur_ids”的参数现在是一个数组。这是唯一的区别。

我做错了什么?

只是为了澄清:这两段代码都能够将新记录添加到livres db表中,但只有第一个代码才能将相应的记录添加到auteurs_livres db表中。第二个根本不会在auteurs_livres中插入任何内容。

(我在ruby 1.9.3p194和rails 4.0.1上运行)

谢谢!


答案

对于遇到同样问题的好人来说,这就是答案:

修改您的控制器并将允许的参数从:auteur_ids更改为{:auteur_ids => []}

params.require(:livre).permit(:name, {:auteur_ids => []})

它现在有效:)

2 个答案:

答案 0 :(得分:1)

对于遇到同样问题的好人来说,这就是答案:

修改您的控制器并将允许的参数从:auteur_ids更改为{:auteur_ids => []}

params.require(:livre).permit(:name, {:auteur_ids => []})

它现在有效:)

答案 1 :(得分:0)

你制定了解决方案,因为Rails现在希望auteur_ids是一个数组,而不是一个项目。这意味着它不是将单个实体传递给模型,而是将params打包为[0][1][2]等,这就是现在提交HABTM记录的方法

还有一种Rails方法可以做到这一点,即使用accepts_nested_attributes_for。这看起来似乎要做得更多,但它会让你的系统变得干涸,并且还能确保约定优于配置:

<强>模型

class Livre < ActiveRecord::Base
  has_and_belongs_to_many : auteurs
  accepts_nested_attributes_for :auteurs
end

class Auteur < ActiveRecord::Base
  has_and_belongs_to_many :livres
end

<强>控制器

def new
  @livre = Livre.new
  @livre.auteurs.build

  @auteurs = Auteur.all
end

def create
  @livre = Livre.new(livre_params)
  if @livre.save
    redirect_to [:admin, @livre]
  else
    render 'new'
  end
end

private
  def livre_params
    params.require(:livre).permit(:name, auteur_attributes: [:auteur_id])
  end

<强>表格

<%= form_for @livre do |f| %>
    <%= f.text_field :your_current_vars %>
    <%= f.fields_for :auteurs do |a| %>
        <%= a.collection_select(:auteur_id, @auteurs, :id, :name, {}) %>
    <% end %>
<% end %>

这将为您提交auteur_id(并自动将livre_id外键与HABTM模型相关联。目前,这只会提交new动作中构建的对象数量 - - 所以为了添加更多项目,你必须建立更多