轨道 4 HABTM 在我向collection_select添加"multiple true"时停止工作



在过去的几天里,我在谷歌上搜索并尝试了我能想到的一切,以解决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辅助对象时,(现在是multiple)关系将不再保存。样本代码:

(型号和控制器不变)

视图:

<% 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"}

正如您所看到的,"auter_ids"的params现在是一个数组。这是唯一的区别。

我做错了什么?

澄清一下:这两段代码都可以向livresdb表添加新记录,但只有第一段代码能够向auteurs_livresdb表添加适当的记录。第二个简单地不向auteurs_livres中插入任何内容。

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

谢谢!


回答

对于那些陷入同样问题的优秀人士,以下是答案:

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

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

现在它可以工作了:)

对于那些遇到同样问题的优秀人士,以下是答案:

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

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

现在它可以工作了:)

您之所以制定了解决方案,是因为Rails现在希望auteur_ids是一个数组,而不是单个项。这意味着,它不只是将单个实体传递给模型,而是将参数打包为[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 %>

这将为您提交auter_id(并自动关联HABTM模型中的livre_id外键。目前,这只会提交在new操作中构建的对象数量——因此,为了添加更多项目,您必须构建更多

最新更新