Rails4中的嵌套简单表单 – 有很多通过,保存多个记录
通过关系,我有一个标准的has_many。 通过连接表交互,人类拥有许多兽人。 互动只是一个表格和模型; 没有控制器或视图。
使用Rails 4中的simpleform gem,我想从人体页面创建一个表单,以便从所有兽人的池中选择多个兽人。 提交后,我希望它在交互表中创建/更新尽可能多的记录,每个记录都包含人员ID,并且选择了多个orc id。 :
AKA列表符号
- 从一端制作表格(人类)
- 列出表格中的所有兽人
- 从该列表中选择多个兽人
- 使用
human_id
和orc_id
将多个记录保存到交互表中,因为从该列表中选择了兽人。 (human_id在这些记录中将是相同的,因为它从给定的人类表单页面开始)
我将尽可能多地编写整个故事的代码。 请随时要求澄清,并解决任何错误,以实现这一点。
表
humans integer "id" interactions integer "human_id" integer "orc_id" index ["human_id", "orc_id"] # This is the primary key. no normal id. # Is it better to have a primary id for this join table, or does it not matter? orcs integer "id"
楷模
/models/human.rb
class Human < ActiveRecord::Base has_many :interaction has_many :orcs, through: :interactions accepts_nested_attributes_for :interactions end
/models/interaction.rb
# Purely a join model and table. No controller, no scaffold. class Interaction <ActiveRecord::Base belongs_to :human belongs_to :orc accepts_nested_attributes_for :orc # Singular to match what was specified in the belongs_to relationship? # Do I even need this if I'm only trying to read orcs to save their id into the interactions table, and not trying to modify orcs? end
/models/orc.rb
class Orc< ActiveRecord::Base has_many :interactions has_many :humans, through: :interactions end
控制器
/controllers/humans_controller.rb
class HumansController < ApplicationController before_action :set_human, only: [:show, :edit, :update, :destroy] before_action :build_interaction, only: [:new, :edit] private def set_human @human = Human.find(params[:id]) end def human_params params.require(:human).permit( interaction_attributes: [:human_id, :orc_ids, # Is plural here correct? :_destroy] ) end def build_interaction @interaction = @human.interactions.build # Is the human instance variable valid here? # How many interactions are being built here? # How do I ensure there are as many interaction builds as there will be selected orcs (ie as many interaction records to be saved or updated)? end end
/controllers/orcs_controller.rb
class OrcsController < ApplicationController before_action :set_orc, only: [:show, :edit, :update, :destroy] private def set_orc @orc = Orc.find(params[:id]) end def orc_params params.require(:orc).permit() end end
查看
/views/humans/_form.html.haml
= simple_form_for(@human, html: { multipart: true }) do |f| = f.simple_fields_for :interactions do |i| = i.hidden_field :human_id, value: @human.id = i.association :orc, collection: Orc.all ^ # Should this be :orc_id? # Does this code automatically extract the orc_id when saving to the interactions table?
谢谢。
我错过了什么? 当我提交时,我确认在交互连接表中没有创建记录。
我认为有些挑战是
- 重复使用单个隐藏输入字段创建多个记录。
- 当交互表必须是单个orc时,获取一个orcs列表(因为它是在交互模型中使用belongs_to:orc定义的)
另外,在哪里可以找到更多关于如何使用复数forms的模型ID的工作(即简单地使用orc_ids
而不是orc_id
,以及需要具体的后果)?
事实certificate,使用simple_form
这实际上相当简单(谁知道?)。 它处理所有中间表的魔力(与Rails的真棒一起)。 你需要做的就是:
= simple_form_for(@human, html: { Pmultipart: true }), do |f| = f.association :orcs
我没有真正使用HAML所以在do |f|
之前我不确定这个逗号 。 以下是我在ERB HTML中要说的内容
<%= simple_form_for(@human) do |f| %> <%= f.association :orcs %> <% end %>
然后在你的控制器的param清洁剂中:
def orc_params params.require(:orc).permit(orc_ids: []) end
最后在你的模型中:
class Human < ActiveRecord::Base ... accepts_nested_attributes_for :orcs end
就是这样! 它将自动创建连接对象。 你不喜欢魔法吗?
这将生成由所有兽人填充的多选字段。 您可以使用f.association :orcs, as: :check_boxes
轻松地将其更改为复选框f.association :orcs, as: :check_boxes
。
- 动态创建has_many或habtm的after_add和after_remove回调?
- Rails STI和has_many通过关联不起作用,SQLException:没有这样的表
- 使ActiveRecord连接模型属性在查询结果中可用
- 使用has_many:通过和构建
- NameError:has_many通过关系的未初始化常量
- has_many通过表单和添加属性来连接表
- Rails:ActiveRecord :: HasManyThroughSourceAssociationNotFoundError:找不到源关联
- Rails has_many:通过条件和建立关联
- 友谊has_many通过模型与多个状态’