5

我编写了一个 gem,它允许将 Google 电子表格转换为 Rails 模型。这个过程的顺序包括创建所有模型,然后连接它们的关联,然后保存所有模型。它支持所有可用的关联类型,并且在每种情况下,创建模型、建立关联、然后保存模型都可以正常工作。例外情况如下:

我有一个简单的has_one, through关联(为简洁起见省略了属性访问):

class Left < ActiveRecord::Base
   has_many :middles, dependent: :destroy
   has_many :rights, through: :middles
end

class Right < ActiveRecord::Base 
   has_one :middle, dependent: :destroy
   has_one :left, through: :middle
end

class Middle < ActiveRecord::Base
  belongs_to :left
  belongs_to :right
end

我发现一些不一致的行为取决于关联分配的哪一方:

从右到左分配:

left = Left.new
right = Right.new
left.rights << right
left.middles #[]
right.middle #nil
left.save!
left.middles # <Middle theme_id: 1, archive_resource_id: 1 >

从右到左分配:

left = Left.new
right = Right.new
right.left = left
left.middles #[]
right.middle <Middle theme_id: nil, archive_resource_id: nil >
right.save!
right.middle # <Middle theme_id: nil, archive_resource_id: 1 >

这种行为似乎非常不一致。为什么是这样?为什么这是一种方式而不是另一种方式?有没有办法与两个未保存的记录建立这种关系?

我很欣赏显而易见的解决方案是在建立关系之前保存所有内容,但如上所述,我需要在建立关联时取消保存模型,并且在所有其他类型的关联中,这方面没有问题。

4

3 回答 3

0

根据 Rails API 文档(链接)-

如果您在连接模型上使用 belongs_to,最好在 belongs_to 上设置 :inverse_of 选项,这意味着以下示例可以正常工作(其中 tags 是 has_many :through 关联):

所以@Kaleidoscope 建立的关联其实是正确的。

于 2013-11-07T14:30:11.657 回答
0

我认为它没有用,因为你有

has_many - has_one

左右之间的关系而不是

has_many - 属于_to

另一方面

属于_to :left, through: :middle

不可能。所以你应该使用delegate for getter并自己编写setter方法,像这样

class Right < ActiveRecord::Base 
  has_one :middle, dependent: :destroy
  delegate :left, to: :middle

  def left=(left)
    #logic
  end
end
于 2013-11-08T21:11:21.810 回答
-1

我认为它可能有效,但不会立即更新。true在调用关联方法时尝试传递。前任。right.middle(true). 这将迫使 Rails 返回数据库以获取记录,而不是检查过时的缓存。但是不要对新记录执行此操作,因为您会破坏内存中的关联对象。

为避免强制重新加载,请设置inverse_of您的关联:

class Left < ActiveRecord::Base
   has_many :middles, dependent: :destroy, inverse_of: :left
   has_many :rights, through: :middles
end

class Right < ActiveRecord::Base 
   has_one :middle, dependent: :destroy, inverse_of: :right
   has_one :left, through: :middle
end

class Middle < ActiveRecord::Base
  belongs_to :left, inverse_of: :middles
  belongs_to :right, inverse_of: :middle
end

inverse_of了解关联模型与自身的关系,这使其model能够“智能”地持久化和加载关联对象。

于 2013-11-05T06:00:12.650 回答