我通过关系得到了一个标准的 has_many 。
人类通过一个连接表与许多兽人进行交互。交互只是一个表格和模型;没有控制器或视图。
使用 Rails 4 中的 simpleform gem,我想从人类页面创建一个表单,以便从所有兽人池中选择多个兽人。提交后,我希望它在交互表中创建/更新尽可能多的记录,每个记录都有人类 ID,并选择尽可能多的兽人 ID。 :
又名列表表示法
- 从一端制作一个表格(人类)
- 列出表格中所有的兽人
- 从该列表中选择多个兽人
- 将尽可能多的记录保存到交互表中
human_id
and orc_id
因为兽人是从该名单中选出的。 (这些记录中的 human_id 是相同的,因为它是从给定的人类表单页面开始的)
我将尽可能多地编写整个故事的代码。请随时要求澄清,并修复任何错误以实现此目的。
Tables
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
/模型/人类.rb
class Human < ActiveRecord::Base
has_many :interaction
has_many :orcs, through: :interactions
accepts_nested_attributes_for :interactions
end
/模型/交互.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 (i.e. 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
/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?
谢谢。
我缺少什么?
当我提交时,我确认交互连接表中没有创建任何记录。
我认为一些挑战是
- 重用单个隐藏输入字段创建多个记录。
- 当交互表必须是单个兽人时获取兽人列表(因为它是在交互模型中使用belongs_to :orc定义的)
另外,我在哪里可以找到更多关于如何使用模型 id 的复数形式的信息(即简单地使用orc_ids
代替orc_id
,以及这会带来什么具体后果)?