【问题标题】:Rails 6 - create has_many through recordRails 6 - 通过记录创建 has_many
【发布时间】:2020-11-20 23:39:38
【问题描述】:

为什么 CompaniesController 不使用 current_user.companies.build(company_params) 创建记录 CompanyUser? 如何在创建公司记录时创建 CompanyUser 记录?

型号:

用户

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

公司

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

公司用户

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

迁移

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

【问题讨论】:

  • 这能回答你的问题吗? - stackoverflow.com/a/9346642
  • current_user.companies.build(company_params) 应该创建一个带有 CompanyUser 记录的公司吗?
  • 在 Rails 5+ belongs_to 关联默认情况下是非可选的。 CompanyUser 中的这两个验证完全是多余的,可能是问题的根源。另外,您实际上是如何测试的?
  • @max 我正在创建一家公司。如果我删除两个验证,仍然不会创建 CompanyUser 记录。

标签: ruby-on-rails


【解决方案1】:

您需要在 CompanyUser 模型中的 belongs_to 关联上设置 :inverse_of 选项,并在 ComapanyUser 中删除 :company_id:user_id 上的存在验证才能使此工作正常进行。 ComapanyUser 模型应如下所示:

class CompanyUser < ApplicationRecord
  include Userstampable::Stampable

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

检查 ActiveRecord 关联 docs:through 选项的描述。它提到您需要:inverse_of 来创建连接模型记录。

如果您要修改关联(而不是仅仅从 它),那么最好设置 :inverse_of 选项 连接模型上的源关联。这允许关联的记录 将被构建,它将自动创建适当的连接模型 保存时的记录。 (请参阅“关联加入模型” 上一节。)

【讨论】:

    猜你喜欢
    • 2017-01-24
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    • 2016-04-22
    • 2013-01-08
    • 1970-01-01
    相关资源
    最近更新 更多