使用accepts_nested_attributes_for创建带有rails的双嵌套记录

时间:2017-09-13 21:52:59

标签: ruby-on-rails

我正在使用Rails 5,但我在使用accepts_nested_attributes_for创建双重嵌套记录时遇到问题。我的模型看起来像这样:

Class Quote < ApplicationRecord
  has_many :terms, inverse_of: :quote
  has_many :mileages, inverse_of: :quote
end

Class Term < ApplicationRecord
  belongs_to :quote, optional: true
end

Class Mileage < ApplicationRecord
  belongs_to :quote, optional: true
end

Class Residual < ApplicationRecord
  belongs_to :term, optional: true
  belongs_to :mileage, optional: true
end

我正在尝试使用accepts_nested_attributes_for在创建新报价时创建剩余记录。它适用于Term和Mileage,甚至Rebate和MoneyFactor都是在Term下嵌套的(我将它们留下来因为它们工作正常), 但是我在尝试创建Residual时遇到了困难,因为它属于两个属于Quote的不同模型。我已经阅读了很多关于nested_attributes_for的帖子,但似乎都没有处理这种特定的情况。

我的QuotesController创建动作:

  def create
    @quote = Quote.new(quote_params)
    @quote.user_id = current_user.id

    if @quote.save
      @quotes = current_user.quotes.includes(:terms, :rebates, 
       :money_factors, :residuals, :mileages)
       render :index
    else
     render json: @quote, status: 422
    end
  end

以下是我的报价控制器中的强力参数:

  def quote_params
    params.require(:quote).permit(:user_id, :lead_id, :year, :make, 
     :make_id, :model, :model_id, :trim, :trim_id, :title, :msrp, :sell_price, :profit, :customer_cash, :bank_fee_plan,
  :registration_plan, :smog_plan, :misc_fee_plan, :rebate_tax_plan, :doc_fee_plan,
  :down_payment, :drive_off, :monthly_payment, :tax, :bank_fee, :registration, :doc_fee, :smog,
  :misc_fee, :rebate_tax,

  mileages_attributes: [:id, :quote_id, :mileage,
    residual_attributes: [:id, :term_id, :mileage_id, :residual]
  ],
  terms_attributes: [
    :id,
    :months,
    rebates_attributes: [:id, :term_id, :amount],
    money_factors_attributes: [:id, :term_id, :money_factor],
    residuals_attributes: [:id, :term_id, :mileage_id, :residual]
  ]
)
  end

我在前端使用React和Redux,所以这就是我的观点:

const quote = merge({}, this.state, {
  terms_attributes: [{
    months: this.state.months,
    rebates_attributes: [{ amount: this.state.rebate }],
    money_factors_attributes: [{ money_factor: this.state.money_factor }],
    residuals_attributes: [{ residual: this.state.residual }]
  }],
  mileages_attributes: [{ mileage: this.state.mileage, residuals_attributes: [{ residual: this.state.residual }] }],
});

这是我的完整报价,期限,里程和剩余模型:

class Quote < ApplicationRecord

 validates :user_id, presence: true

 belongs_to :user
 belongs_to :lead, optional: true

 has_many :mileages, dependent: :destroy, inverse_of: :quote

 has_many :terms, dependent: :destroy, inverse_of: :quote

 has_many :rebates,
  through: :terms,
  source: :rebates

 has_many :money_factors,
  through: :terms,
  source: :money_factors

 has_many :residuals,
  through: :mileages,
  source: :residuals

 has_many :residuals,
  through: :terms,
  source: :residuals


 accepts_nested_attributes_for :mileages, :terms, allow_destroy: true

end

class Term < ApplicationRecord

 validates :months, presence: true

 belongs_to :quote, optional: true

 has_many :rebates, dependent: :destroy
 has_many :money_factors, dependent: :destroy
 has_many :residuals, dependent: :destroy

 accepts_nested_attributes_for :rebates, :money_factors, :residuals, 
allow_destroy: true

end

class Mileage < ApplicationRecord

 validates :mileage, presence: true

 belongs_to :quote, optional: true

 has_many :residuals, dependent: :destroy

 accepts_nested_attributes_for :residuals, allow_destroy: true
end

class Residual < ApplicationRecord

 validates :residual, presence: true

 belongs_to :term, optional: true
 belongs_to :mileage, optional: true
end

1 个答案:

答案 0 :(得分:0)

您仍然可以使用#accepts_nested_attributes_for。你有两个选择:设置两个一对多关系或使用多态。假设Residual已有term_idmileage_id列,您可以在has_many :residualsTerm中添加Mileage

多态性: 这使您可以为Residual设置一个界面,以使用任意数量的模型。

Class Term < ApplicationRecord
  belongs_to :quote, optional: true
  has_many: residuals, as: :residualable 
end

Class Mileage < ApplicationRecord
  belongs_to :quote, optional: true
  has_many: residuals, as: :residualable
end

Class Residual < ApplicationRecord
  belongs_to :residualable, polymorphic: true, optional: true
end

确保您的Residuals表中有residualable_idresidualable_type列。