Rails - 使用嵌套属性在has_many中发出问题

时间:2015-12-17 05:58:08

标签: ruby-on-rails nested-attributes has-many-through

我遇到了通过与嵌套属性的关系保存has_many的问题。由于应用程序的复杂性和要求,关系如下:

表格结构,

agreements:
  id

agreement_rooms:
  id
  agreement_id
  room_id

details:
  id
  agreement_rooms_id

有关更多说明,agreement_rooms表与许多其他模型相关,其中包含agreement_rooms_id。

Rails Associations,

class Agreement < ActiveRecord::Base
  has_many :details,:through => :agreement_rooms
  accepts_nested_attributes_for :details
end

class AgreementRoom < ActiveRecord::Base
  has_many :details
end

class Detail < ActiveRecord::Base
  belongs_to :agreement_room
  accepts_nested_attributes_for :agreement_room
end

当我尝试使用详细信息哈希创建协议记录时,我收到以下错误,

Agreement.last.details.create()

ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection: Cannot modify association 'agreement#details' because the source reflection class 'Detail' is associated to 'agreementRoom' via :has_many.

我不确定如何通过上述示例的关系使用has_many这个嵌套的属性。请帮忙解决问题。

提前致谢。

3 个答案:

答案 0 :(得分:0)

#app/models/aggreement.rb
class Agreement < ActiveRecord::Base
   has_many :agreement_rooms
   accepts_nested_attributes_for :agreement_rooms
end

#app/models/agreement_room.rb
class AgreementRoom < ActiveRecord::Base
   belongs_to :agreement
   belongs_to :room

   has_many :details
   accepts_nested_attributes_for :details
end

#app/models/room.rb
class Room < ActiveRecord::Base
   has_many :agreement_rooms
   has_many :agreements, through: :agreement_rooms
end

#app/models/detail.rb
class Detail < ActiveRecord::Base
   belongs_to :agreement_room
end

-

#app/controllers/agreements_controller.rb
class AgreementsController < ApplicationController
   def new
      @agreement = Agreement.new
      @agreement.agreement_rooms.build.details.build
   end

   def create
      @agreement = Agreement.new agreement_params
      @agreement.save
   end

   private

   def agreement_params
      params.require(:agreement).permit(:agreement, :param, agreement_rooms_attributes: [ details_attributes: [:x] ])
   end
end

#app/views/agreements/new.html.erb
<%= form_for @agreement do |f| %>
   <%= f.fields_for :agreement_rooms do |ar| %>
      <%= ar.fields_for :details do |d| %>
         <%= d.text_field :x %>
      <% end %>
   <% end %>
   <%= f.submit %>
<% end %>

答案 1 :(得分:0)

您需要定义两个关联:

class Agreement < ActiveRecord::Base
  has_and_belongs_to_many :agreement_rooms # or has_many if you prefer
  has_many :details,:through => :agreement_rooms
  accepts_nested_attributes_for :details
end

检查the docs

答案 2 :(得分:0)

正如我在模型协会设计之前所说的那样,我们不合适,并且由于维护不善,它必须以同样的方式,至少是现在。所以我不得不写一个脏补丁来修复它。

它只是单独跳过此特定模型的嵌套属性,因此可以通过将主记录ID传递给此记录来单独保存。

作为一个肮脏的解决方案,我没有将其标记为答案。只是添加了它,希望有人可以在需要时找到解决方案。

感谢您的帮助