【问题标题】:Multiple Select many to many Ruby on Rails not creating associative records多选多选 Ruby on Rails 不创建关联记录
【发布时间】:2019-08-14 15:54:16
【问题描述】:

好吧,我在一个名为 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

这是迁移表:

    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

【问题讨论】:

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 ruby-on-rails-5


【解决方案1】:

在我看来,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

【讨论】:

  • 它成功了@jvillian,非常感谢。现在更新,我必须使用相同的控制器方法?
  • 好的,我明白了。
  • 那是一个总的奖励答案。你欠我一杯啤酒,k?
  • 但是假设我还有一个多对多的交互,用户和诉讼之间的所谓“被动”,这种方法是行不通的,对吧?
  • 现在,这是一个完全不同的问题。摆出这样的姿势,我来看看。你需要提供一些关于什么是“被动”的信息。并且,也许,用户与联系人在主动和被动方面有何不同。但是,是的,它可能需要修改才能工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多