Rails 通过关系在 has_many 中具有嵌套属性的表单
Rails form with nested attributes in has_many through relationship
我正在尝试使用 has_many :through
关系中的多个嵌套对象构建表单。但是,嵌套对象在保存时似乎没有被分配父对象的 foreign_key。我不确定我在这里做错了什么。
# app/models/admin/host.rb
class Admin::Host < ApplicationRecord
has_many :admin_host_users, class_name: 'Admin::HostUser', foreign_key: 'admin_host_id', dependent: :destroy
has_many :users, through: :admin_host_users
accepts_nested_attributes_for(:admin_host_users, allow_destroy: true)
# app/models/admin/host_user.rb
class Admin::HostUser < ApplicationRecord
belongs_to :admin_host, class_name: 'Admin::Host'
belongs_to :user
# app/models/user.rb
class User < ApplicationRecord
has_many :admin_host_users, class_name: 'Admin::HostUser'
has_many :admin_hosts, through: :admin_host_users
# app/controllers/hosts_controller.rb
class HostsController < ApplicationController
def create
@host = Admin::Host.new(admin_host_params.merge(status: :pending))
@host.save!
end
def new
@host = Admin::Host.new
@admin_host_users = [@host.admin_host_users.build(user: current_user)]
end
private
def admin_host_params
params.require(:admin_host).permit(
:name,
admin_host_users_attributes: [
:user_id,
:role,
],
)
end
# app/views/hosts/_form.html.erb
<%= form_with(model: @host, url: hosts_path, local: true) do |f| %>
<% @admin_host_users.each do |admin_host_user| %>
<%= f.fields_for(:admin_host_users, admin_host_user) do |admin_host_user_form| %>
<%= admin_host_user_form.select(:user_id, @all_users) %>
好的,这就是代码。这是提交表单时的回复:
Started POST "/hosts" for ::1 at 2021-05-23 08:45:22 -0400
Processing by HostsController#create as HTML
Parameters: {"utf8"=>"✓", "admin_host"=>{"name"=>"Test", "admin_host_users_attributes"=>{"0"=>{"user_id"=>"1"}}}, "commit"=>"Apply Now"}
Completed 422 Unprocessable Entity in 287ms (ActiveRecord: 42.5ms)
ActiveRecord::RecordInvalid (Validation failed: Admin host users admin host must exist):
app/controllers/hosts_controller.rb:10:in `create'
尝试在 has_many 关联上设置 inverse_of 选项
has_many :admin_host_users, class_name: 'Admin::HostUser', foreign_key: 'admin_host_id', dependent: :destroy, inverse_of: 'Admin::Host'
has_many :users, through: :admin_host_users, inverse_of: 'Admin::Host'
我正在尝试使用 has_many :through
关系中的多个嵌套对象构建表单。但是,嵌套对象在保存时似乎没有被分配父对象的 foreign_key。我不确定我在这里做错了什么。
# app/models/admin/host.rb
class Admin::Host < ApplicationRecord
has_many :admin_host_users, class_name: 'Admin::HostUser', foreign_key: 'admin_host_id', dependent: :destroy
has_many :users, through: :admin_host_users
accepts_nested_attributes_for(:admin_host_users, allow_destroy: true)
# app/models/admin/host_user.rb
class Admin::HostUser < ApplicationRecord
belongs_to :admin_host, class_name: 'Admin::Host'
belongs_to :user
# app/models/user.rb
class User < ApplicationRecord
has_many :admin_host_users, class_name: 'Admin::HostUser'
has_many :admin_hosts, through: :admin_host_users
# app/controllers/hosts_controller.rb
class HostsController < ApplicationController
def create
@host = Admin::Host.new(admin_host_params.merge(status: :pending))
@host.save!
end
def new
@host = Admin::Host.new
@admin_host_users = [@host.admin_host_users.build(user: current_user)]
end
private
def admin_host_params
params.require(:admin_host).permit(
:name,
admin_host_users_attributes: [
:user_id,
:role,
],
)
end
# app/views/hosts/_form.html.erb
<%= form_with(model: @host, url: hosts_path, local: true) do |f| %>
<% @admin_host_users.each do |admin_host_user| %>
<%= f.fields_for(:admin_host_users, admin_host_user) do |admin_host_user_form| %>
<%= admin_host_user_form.select(:user_id, @all_users) %>
好的,这就是代码。这是提交表单时的回复:
Started POST "/hosts" for ::1 at 2021-05-23 08:45:22 -0400
Processing by HostsController#create as HTML
Parameters: {"utf8"=>"✓", "admin_host"=>{"name"=>"Test", "admin_host_users_attributes"=>{"0"=>{"user_id"=>"1"}}}, "commit"=>"Apply Now"}
Completed 422 Unprocessable Entity in 287ms (ActiveRecord: 42.5ms)
ActiveRecord::RecordInvalid (Validation failed: Admin host users admin host must exist):
app/controllers/hosts_controller.rb:10:in `create'
尝试在 has_many 关联上设置 inverse_of 选项
has_many :admin_host_users, class_name: 'Admin::HostUser', foreign_key: 'admin_host_id', dependent: :destroy, inverse_of: 'Admin::Host'
has_many :users, through: :admin_host_users, inverse_of: 'Admin::Host'