Rails 上的多个 Select 多对多 Ruby 未创建关联记录
Multiple Select many to many Ruby on Rails not creating associative records
好吧,我在 table 名为 Actives 的联系人和诉讼之间建立了多对多关联。在这种情况下,我试图在诉讼中添加许多联系人。问题是:如果 select 是多个,则主动不在诉讼中保存,仅当多个:false.
这是模型:
#contact.rb
class Contact < ActiveRecord::Base
...
has_many :actives
has_many :lawsuits, through: :actives
#lawsuit.rb
class Lawsuit < ActiveRecord::Base
...
has_many :actives
has_many :contacts, through: :actives
accepts_nested_attributes_for :actives, allow_destroy: true
#active.rb
class Active < ActiveRecord::Base
...
belongs_to :lawsuit
belongs_to :contact
这是迁移 table:
class CreateActives < ActiveRecord::Migration
def change
create_table :actives do |t|
t.belongs_to :contact, index: true
t.belongs_to :lawsuit, index: true
t.datetime :appointment_date
t.timestamps
end
end
end
控制器:
#controller/lawsuit.rb
#create method
def create
@lawsuit = Lawsuit.new(lawsuit_params)
respond_to do |format|
if @lawsuit.save
format.html { redirect_to @lawsuit, notice: 'Lawsuit was successfully created.' }
format.json { render :show, status: :created, location: @lawsuit }
else
format.html { render :new }
format.json { render json: @lawsuit.errors, status: :unprocessable_entity }
end
end
end
#require params
params.require(:contact).permit(:name, :lastname, :cpf, :rg, :birthdate, :profession_id, :marital_status_id, :address,
:zipcode, :city, :state, :district, :number, :actives)
视图和输出参数:
#/views/lawsuits/_form.html.erb
<%= form_for @lawsuit, html: {class: "ui form"} do |f| %>
...
<%= f.fields_for :actives do |w| %>
<%= w.select(:contact_id, Contact.all.pluck(:name,:id), {}, {class:"selectize-generic", multiple: true}) %>
<% end %>
<%= f.submit %>
#Params:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9dpRjs0e2iQXgYzNqObSyzuvEnVdQYVHos922hbu0UptxiVeZfJgxgbfgFGKOUR16119VFLOfheNGogAOwez/w==",
"lawsuit"=>{"autos"=>"", "forum_id"=>"1", "lawyer_id"=>"4", "conciliation_date"=>"", "instruction_date"=>"", "fees"=>"",
"actives_attributes"=>{"0"=>{"contact_id"=>["", "2", "7", "9"]}}}, "commit"=>"Create Lawsuit"}
在上次保存的诉讼中:
rails c
x = Lawsuit.last
=> #<Lawsuit id: 17, forum_id: 1, lawyer_id: 4, fees: nil, autos: "", conciliation_date: "", instruction_date: "", created_at: "2019-08-14 15:43:18", updated_at: "2019-08-14 15:43:18">
x.actives
=> #<ActiveRecord::Associations::CollectionProxy [#<Active id: 9, contact_id: nil, lawsuit_id: 17, appointment_date: nil, created_at: "2019-08-14 15:43:18", updated_at: "2019-08-14 15:43:18">]>
我在这上面浪费了很多时间,我已经尝试了一切,重新创建模型,尝试了 simple_form gem,更改了参数等等。我迷路了。
有人可以帮忙吗?
GitHub 项目:
https://github.com/killerowns/lawsuit-manager-rails
在我看来,Active
对您的模型来说是一个令人作呕的名字。为什么不叫它LawsuitContact
呢?然后做:
# == Schema Information
#
# Table name: lawsuit_contacts
#
# id :integer not null, primary key
# lawsuit_id :integer
# contact_id :integer
# appointment_date :datetime
# created_at :datetime not null
# updated_at :datetime not null
#
class LawsuitContact < ActiveRecord::Base
belongs_to :lawsuit
belongs_to :contact
end
然后:
class Contact < ActiveRecord::Base
has_many :lawsuit_contacts
has_many :lawsuits, through: :lawsuit_contacts
end
并且:
class Lawsuit < ActiveRecord::Base
has_many :lawsuit_contacts
has_many :contacts, through: :lawsuit_contacts
end
鉴于您的 params
看起来像:
{
"lawsuit"=>{
"autos"=>"",
"forum_id"=>"1",
"lawyer_id"=>"4",
"conciliation_date"=>"",
"instruction_date"=>"",
"fees"=>"",
"actives_attributes"=>{
"0"=>{
"contact_id"=>["", "2", "7", "9"]
}
}
},
"commit"=>"Create Lawsuit"
}
...在您的控制器中,您可以执行以下操作:
def create
@lawsuit = Lawsuit.new(lawsuit_params)
respond_to do |format|
if @lawsuit.save
@lawsuit.contacts << Contact.where(id: contact_ids)
format.html { redirect_to @lawsuit, notice: 'Lawsuit was successfully created.' }
format.json { render :show, status: :created, location: @lawsuit }
else
format.html { render :new }
format.json { render json: @lawsuit.errors, status: :unprocessable_entity }
end
end
end
def update
@lawsuit = Lawsuit.find_by(id: params[:id])
respond_to do |format|
if @lawsuit.update(lawsuit_params)
# Assuming the user can remove a contact from a lawsuit, you'll want to
# 'unlink' the lawsuit and the contact by destroying all the relevant
# LawsuitContact join models:
@lawsuit.lawsuit_contacts.where.not(contact_id: contact_ids).destroy_all
# Then, you'll want to add any new contacts that the user might have
# added:
@lawsuit.contacts << Contact.where(id: contact_ids)
format.html { redirect_to @lawsuit, notice: 'Lawsuit was successfully updated.' }
format.json { render :show, status: :created, location: @lawsuit }
else
format.html { render :edit }
format.json { render json: @lawsuit.errors, status: :unprocessable_entity }
end
end
end
private
def lawsuit_params
params.require(:lawsuit).permit(
:autos,
:forum_id,
:lawyer_id,
:conciliation_date,
:instruction_date,
:fees
)
end
def contact_ids
params[:lawsuit][:actives_attributes].try(:[], '0').try(:[], :contact_id)
end
好吧,我在 table 名为 Actives 的联系人和诉讼之间建立了多对多关联。在这种情况下,我试图在诉讼中添加许多联系人。问题是:如果 select 是多个,则主动不在诉讼中保存,仅当多个:false.
这是模型:
#contact.rb
class Contact < ActiveRecord::Base
...
has_many :actives
has_many :lawsuits, through: :actives
#lawsuit.rb
class Lawsuit < ActiveRecord::Base
...
has_many :actives
has_many :contacts, through: :actives
accepts_nested_attributes_for :actives, allow_destroy: true
#active.rb
class Active < ActiveRecord::Base
...
belongs_to :lawsuit
belongs_to :contact
这是迁移 table:
class CreateActives < ActiveRecord::Migration
def change
create_table :actives do |t|
t.belongs_to :contact, index: true
t.belongs_to :lawsuit, index: true
t.datetime :appointment_date
t.timestamps
end
end
end
控制器:
#controller/lawsuit.rb
#create method
def create
@lawsuit = Lawsuit.new(lawsuit_params)
respond_to do |format|
if @lawsuit.save
format.html { redirect_to @lawsuit, notice: 'Lawsuit was successfully created.' }
format.json { render :show, status: :created, location: @lawsuit }
else
format.html { render :new }
format.json { render json: @lawsuit.errors, status: :unprocessable_entity }
end
end
end
#require params
params.require(:contact).permit(:name, :lastname, :cpf, :rg, :birthdate, :profession_id, :marital_status_id, :address,
:zipcode, :city, :state, :district, :number, :actives)
视图和输出参数:
#/views/lawsuits/_form.html.erb
<%= form_for @lawsuit, html: {class: "ui form"} do |f| %>
...
<%= f.fields_for :actives do |w| %>
<%= w.select(:contact_id, Contact.all.pluck(:name,:id), {}, {class:"selectize-generic", multiple: true}) %>
<% end %>
<%= f.submit %>
#Params:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9dpRjs0e2iQXgYzNqObSyzuvEnVdQYVHos922hbu0UptxiVeZfJgxgbfgFGKOUR16119VFLOfheNGogAOwez/w==",
"lawsuit"=>{"autos"=>"", "forum_id"=>"1", "lawyer_id"=>"4", "conciliation_date"=>"", "instruction_date"=>"", "fees"=>"",
"actives_attributes"=>{"0"=>{"contact_id"=>["", "2", "7", "9"]}}}, "commit"=>"Create Lawsuit"}
在上次保存的诉讼中:
rails c
x = Lawsuit.last
=> #<Lawsuit id: 17, forum_id: 1, lawyer_id: 4, fees: nil, autos: "", conciliation_date: "", instruction_date: "", created_at: "2019-08-14 15:43:18", updated_at: "2019-08-14 15:43:18">
x.actives
=> #<ActiveRecord::Associations::CollectionProxy [#<Active id: 9, contact_id: nil, lawsuit_id: 17, appointment_date: nil, created_at: "2019-08-14 15:43:18", updated_at: "2019-08-14 15:43:18">]>
我在这上面浪费了很多时间,我已经尝试了一切,重新创建模型,尝试了 simple_form gem,更改了参数等等。我迷路了。 有人可以帮忙吗?
GitHub 项目: https://github.com/killerowns/lawsuit-manager-rails
在我看来,Active
对您的模型来说是一个令人作呕的名字。为什么不叫它LawsuitContact
呢?然后做:
# == Schema Information
#
# Table name: lawsuit_contacts
#
# id :integer not null, primary key
# lawsuit_id :integer
# contact_id :integer
# appointment_date :datetime
# created_at :datetime not null
# updated_at :datetime not null
#
class LawsuitContact < ActiveRecord::Base
belongs_to :lawsuit
belongs_to :contact
end
然后:
class Contact < ActiveRecord::Base
has_many :lawsuit_contacts
has_many :lawsuits, through: :lawsuit_contacts
end
并且:
class Lawsuit < ActiveRecord::Base
has_many :lawsuit_contacts
has_many :contacts, through: :lawsuit_contacts
end
鉴于您的 params
看起来像:
{
"lawsuit"=>{
"autos"=>"",
"forum_id"=>"1",
"lawyer_id"=>"4",
"conciliation_date"=>"",
"instruction_date"=>"",
"fees"=>"",
"actives_attributes"=>{
"0"=>{
"contact_id"=>["", "2", "7", "9"]
}
}
},
"commit"=>"Create Lawsuit"
}
...在您的控制器中,您可以执行以下操作:
def create
@lawsuit = Lawsuit.new(lawsuit_params)
respond_to do |format|
if @lawsuit.save
@lawsuit.contacts << Contact.where(id: contact_ids)
format.html { redirect_to @lawsuit, notice: 'Lawsuit was successfully created.' }
format.json { render :show, status: :created, location: @lawsuit }
else
format.html { render :new }
format.json { render json: @lawsuit.errors, status: :unprocessable_entity }
end
end
end
def update
@lawsuit = Lawsuit.find_by(id: params[:id])
respond_to do |format|
if @lawsuit.update(lawsuit_params)
# Assuming the user can remove a contact from a lawsuit, you'll want to
# 'unlink' the lawsuit and the contact by destroying all the relevant
# LawsuitContact join models:
@lawsuit.lawsuit_contacts.where.not(contact_id: contact_ids).destroy_all
# Then, you'll want to add any new contacts that the user might have
# added:
@lawsuit.contacts << Contact.where(id: contact_ids)
format.html { redirect_to @lawsuit, notice: 'Lawsuit was successfully updated.' }
format.json { render :show, status: :created, location: @lawsuit }
else
format.html { render :edit }
format.json { render json: @lawsuit.errors, status: :unprocessable_entity }
end
end
end
private
def lawsuit_params
params.require(:lawsuit).permit(
:autos,
:forum_id,
:lawyer_id,
:conciliation_date,
:instruction_date,
:fees
)
end
def contact_ids
params[:lawsuit][:actives_attributes].try(:[], '0').try(:[], :contact_id)
end