Rails 5中具有多态关联的嵌套属性

时间:2016-05-07 20:49:19

标签: ruby-on-rails

我已经创建了一个带有多态关联的Address模型,我试图通过客户端模型的嵌套属性保存到它,但我在Address addressable must exist中获得@client.errors }。

型号:

class Client < ApplicationRecord
  has_one :address, as: :addressable, dependent: :destroy
  accepts_nested_attributes_for :address, :allow_destroy => true
end

class Address < ApplicationRecord
  belongs_to :addressable, polymorphic: true
end

控制器:

class ClientsController < ApplicationController

  def new
    @client = Client.new
    @client.create_address
  end

  def create
    @client = Client.new(client_params)

    if @client.save
      ...
    else
      ...
    end
  end

  private
  def client_params
    params.require(:client).permit(:first_name ,:last_name, :company, address_attributes: [:line1, :line2, :line3, :city, :state_province, :postal_code, :country])
  end    
end

3 个答案:

答案 0 :(得分:5)

 belongs_to :xx, polymorphic: true, optional: true

答案 1 :(得分:2)

另外

optional: true 

欺骗问题,您可以通过分两步打破控制器中的创建来保持关系。

def client_params
  params.require(:client).permit(:first_name ,:last_name, :company)
end

def address_params 
 params.require(:client).require( :address_attributes).permit(:line1, :line2, :line3, :city, :state_province, :postal_code, :country )
end

def create
  @client = Client.new(client_params)

  if @client.save
   @client.create_address( address_params )
  ...
这可能看起来更丑陋,但它使关系更安全。

答案 2 :(得分:1)

您应该在belongs_to关系上添加inverse_of键,例如在您的Address班上:

class Address < ApplicationRecord
  belongs_to :addressable, polymorphic: true, inverse_of: :addressable
end

这将正确保存嵌套地址,因为Rails现在可以正确知道要在addressable中分配什么。

除非真正使用optional,否则不要使用addressable键。