Rails4中的嵌套简单表单-具有多次通过,保存多个记录 [英] Nested Simple Form in Rails4 - has many through, save multiple records

查看:84
本文介绍了Rails4中的嵌套简单表单-具有多次通过,保存多个记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个通过关系的标准has_many. 人类通过联接表Interactions拥有许多兽人.交互只是一个表和模型.没有控制器或视图.

I've got a standard has_many through relationship. Humans have many Orcs through a join table Interactions. The interactions is just a table and model; no controller or views.

我想在Rails 4中使用simpleform gem,以便从人员页面中创建一个表单,以便从所有兽人池中选择多个兽人.提交后,我希望它在交互表中创建/更新尽可能多的记录,每条记录都带有人类ID,并选择了尽可能多的Orc ID. :

Using the simpleform gem in Rails 4, I want to make a form from the humans page, in order to select multiple orcs out of the pool of all orcs. Once submitted, I want it to create/update as many records in the interactions table, each with the human id, and as many orc ids were selected. :

又名列表符号

  1. 从一端(人类)开始制作表单
  2. 列出表单中的所有兽人
  3. 从该列表中选择多个兽人
  4. 使用human_idorc_id将尽可能多的记录保存到交互表中,与从该列表中选择的兽人一样. (因为它们是从给定人员的表单页面开始的,所以这些记录中的human_id相同)
  1. Make a form from one end (humans)
  2. List out all the orcs in the form
  3. Select multiple orcs from that list
  4. Save as many records into the interactions table with human_id and orc_id as there were orcs chosen from that list. (The human_id will be the same in these records, since it started from a given human's form page)

我将尽可能完整地编写整个故事.请随时要求澄清,并为解决此问题而修正所有错误.

I'll code out as much of the entire story as I have. Please feel free to ask for clarifications, and fix anything wrong for accomplishing this.

表格

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

/models/human.rb

class Human < ActiveRecord::Base
  has_many :interaction
  has_many :orcs, through: :interactions

  accepts_nested_attributes_for :interactions
end

/models/interaction.rb

/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

/models/orc.rb

class Orc< ActiveRecord::Base
  has_many :interactions
  has_many :humans, through: :interactions

end

控制器

/controllers/humans_controller.rb

/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 (i.e. as many interaction records to be saved or updated)?
    end
end

/controllers/orcs_controller.rb

/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

/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?

谢谢.

我想念什么? 提交时,我确认在交互联接表中没有创建记录.

What am I missing? when I submit, I confirmed that there no record created in the interactions join table.

我认为某些挑战是

  1. 使用单个隐藏的输入字段创建多个记录.
  2. 当交互表必须是单个兽人时获得兽人列表(因为它是在交互模型中用belongs_to:orc定义的)

此外,在哪里可以找到有关使用模型ID的复数形式的更多信息(即,简单地使用orc_ids而不是orc_id以及其带来的具体后果)?

Also, where can I find out more about how using the plural form of model ids works (i.e. simply using orc_ids instead of orc_id, and what concrete consequences that entails)?

推荐答案

事实证明,使用simple_form,这实际上相当简单(谁知道?).它处理所有中间表的魔力(以及Rails的出色表现).您所需要做的就是这个:

Turns out that with simple_form this is actually rather simple (who knew?). It handles the magic of all the intermediary tables (together with Rails's awesomeness). All you need to do is this:

= simple_form_for(@human, html: { Pmultipart: true }), do |f|
  = f.association :orcs

我不是真的使用HAML,所以我不确定do |f|之前的逗号.这就是我要在ERB HTML中说的话

I don't really use HAML so I'm not sure about that comma before do |f|. Here is what I'm trying to say in ERB HTML

<%= simple_form_for(@human) do |f| %>
  <%= f.association :orcs %>
<% end %>

然后在控制器的参数消毒器中:

Then in your controller's param sanitizer:

def orc_params
  params.require(:orc).permit(orc_ids: [])
end

最后在您的模型中:

class Human < ActiveRecord::Base
  ...
  accepts_nested_attributes_for :orcs
end

就是这样!它将自动创建连接对象.你不只是爱魔术吗?

And that's it! It will automatically create the join objects. Don't you just love magic?

这将生成一个由所有兽人填充的多选字段.您可以使用f.association :orcs, as: :check_boxes轻松将其更改为复选框.

This will generate a multi-select field populated by all orcs. You can easily change this to checkboxes by using f.association :orcs, as: :check_boxes.

这篇关于Rails4中的嵌套简单表单-具有多次通过,保存多个记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆