0

我有两个具有 has_many 关联的模型。然而,从“多”来看,只有一个是初级的。这是设计它的一种方法:

方法#1

class Person < ActiveRecord:Base
  has_many :address

  def find_primary
    self.address.where('is_primary = ?', "true").first
  end
end

class Address < ActiveRecord:Base
  belongs_to :person
  attr_protected :is_primary

  def make_primary
    self.person.address.each { |a| a.update_attribute(:is_primary, false) }
    self.update_attribute(:is_primary,true)
  end

  def is_primary?
    self.is_primary
  end
end

我不喜欢make_primary那个人的地址数量的 O(n) 怎么样。这也可能是多线程环境中的问题(即乘客,对吗?)。也许有一个优化make_primary可以更好地用于方法#2?

此外,可能很容易出现难以发现的错误,这些错误允许多个地址成为主要地址。

方法#2

class Person < ActiveRecord:Base
  has_many :address
  belongs_to :primary_address, :class_name => 'Address', :foreign_key => :primary_address_id
end

class Address < ActiveRecord:Base
  belongs_to :person
  has_one :person_as_primary, :class_name => 'Person', :foreign_key => :primary_address_id

  def make_primary
    self.person.primary_address = self
    self.save!
  end
end

除了避免多线程和 O(n) 问题之外,这种方法也find_primary没有必要,因为它只是self.primary_address.

但是,这里的问题是不能保证

[person, nil].include?(person.primary_address.person_as_primary)

以下是我的问题:

1)还有我没有提到的其他优点/缺点吗?

2)我应该考虑哪些其他方法?特别是,有没有没有提出任何上述问题?

4

1 回答 1

0

我会以唯一索引的形式将解决方案下推到数据库中。这保证了一次只能有一个是主要的。如果并发不是问题,那么您可以在 Rails 级别使用唯一性约束,但听起来并发是您的应用程序的一个问题。

于 2013-04-22T17:56:20.277 回答