简体   繁体   English

Rails 6 - 通过记录创建 has_many

[英]Rails 6 - create has_many through record

Why does the CompaniesController not create a record CompanyUser with current_user.companies.build(company_params) ?为什么 CompaniesController 不使用current_user.companies.build(company_params)创建记录 CompanyUser ? How can I create CompanyUser record at the time of creation of the Company record?如何在创建公司记录时创建 CompanyUser 记录?

Models:楷模:

User用户

class User < ApplicationRecord
  has_many :company_users, dependent: :destroy
  has_many :companies, through: :company_users
end

Company公司

class Company < ApplicationRecord
  include Userstampable::Stampable

  has_many :company_users, dependent: :destroy
  has_many :users, through: :company_users

  accepts_nested_attributes_for :company_users, reject_if: :all_blank

  validates :name, presence: true, length: { maximum: 100 }
  validates :description, length: { maximum: 1000 }
end

CompanyUser公司用户

class CompanyUser < ApplicationRecord
  include Userstampable::Stampable

  belongs_to :company
  belongs_to :user

  validates :company_id, presence: true
  validates :user_id, presence: true
end

CompaniesController公司控制器

class CompaniesController < ApplicationController
  def create
    @company = current_user.companies.build(company_params)

    respond_to do |format|
      if @company.save
        format.html { redirect_to @company, notice: 'Company was successfully created.' }
        format.json { render :show, status: :created, location: @company }
      else
        format.html { render :new }
        format.json { render json: @company.errors, status: :unprocessable_entity }
      end
    end
  end

  private

    # Never trust parameters from the scary internet, only allow the white list through.
    def company_params
      params.require(:company).permit(:name, :description)
    end
end

Migrate迁移

class CreateCompanyUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :company_users do |t|
      t.integer :role, default: 0
      t.belongs_to :company, null: false, foreign_key: true
      t.belongs_to :user, null: false, foreign_key: true

      t.timestamps null: false, include_deleted_at: true
      t.userstamps index: true, include_deleter_id: true

      t.index [:company_id, :user_id], unique: true
    end
  end
end

You need to set the :inverse_of option on the belongs_to associations in CompanyUser model and remove the presence validations on :company_id and :user_id in ComapanyUser to make this work.您需要在 CompanyUser model 中的belongs_to关联上设置:inverse_of选项,并删除 ComapanyUser 中的:company_id:user_id上的存在验证以使这项工作正常进行。 The ComapanyUser model should look like this: ComapanyUser model 应如下所示:

class CompanyUser < ApplicationRecord
  include Userstampable::Stampable

  belongs_to :company, inverse_of: :company_users
  belongs_to :user, inverse_of: :company_users
end

Check the description of the :through option in ActiveRecord association docs .检查 ActiveRecord 关联文档中的:through选项的描述。 It mentions that you need :inverse_of to create join model records.它提到您需要:inverse_of来创建连接 model 记录。

If you are going to modify the association (rather than just read from it), then it is a good idea to set the:inverse_of option on the source association on the join model.如果您要修改关联(而不仅仅是从中读取),那么最好在连接 model 的源关联上设置:inverse_of 选项。 This allows associated records to be built which will automatically create the appropriate join model records when they are saved.这允许构建关联的记录,这些记录将在保存时自动创建适当的连接 model 记录。 (See the 'Association Join Models' section above.) (请参阅上面的“关联加入模型”部分。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM