2

我正在尝试通过在 Rails 2.3.x 中使用 named_scopes 来整理我的代码,但我正在努力处理 has_many :through 关联。我想知道我是否将范围放在错误的位置...

下面是一些伪代码。问题是 :accepted 命名范围被复制了两次......我当然可以调用 :accepted 不同的东西,但这些是桌面上的状态,将它们称为不同的东西似乎是错误的。谁能阐明我是否正确执行以下操作?

我知道 Rails 3 已经发布,但它仍处于测试阶段,这是我正在做的一个大项目,所以我还不能在生产中使用它。

class Person < ActiveRecord::Base
  has_many :connections
  has_many :contacts, :through => :connections

  named_scope :accepted, :conditions => ["connections.status = ?", Connection::ACCEPTED]
  # the :accepted named_scope is duplicated
  named_scope :accepted, :conditions => ["memberships.status = ?", Membership::ACCEPTED]
end

class Group < ActiveRecord::Base
  has_many :memberships
  has_many :members, :through => :memberships
end

class Connection < ActiveRecord::Base
  belongs_to :person
  belongs_to :contact, :class_name => "Person", :foreign_key => "contact_id"
end

class Membership < ActiveRecord::Base
  belongs_to :person
  belongs_to :group
end

我正在尝试运行 person.contacts.accepted 和 group.members.accepted 之类的东西,这是两个不同的东西。named_scopes 不应该在 Membership 和 Connection 类中吗?

但是,如果您尝试将命名范围放在 Membership 和 Connection 类中,那么您会收到此错误(因为 Person.find(2).contacts 返回一个没有“接受”方法的 Persons 数组:

>> Person.find(2).contacts.accepted
NoMethodError: undefined method `accepted' for #<Class:0x108641f28>

一种解决方案是仅在 Person 类中将两个不同的命名范围称为不同的东西,甚至创建单独的关联(即 has_many :accepted_members 和 has_many :accepted_contacts),但它看起来很骇人听闻,实际上我不仅仅接受了(即. 禁止成员、忽略连接、待处理、请求等)

4

2 回答 2

0

我确信这不是最好的方法,我相信你可以在模型上做到这一点persongroup但我也相信以下内容对你有用:

# models
class Person < ActiveRecord::Base 
  has_many :connections 
  has_many :contacts, :through => :connections

  has_many :memberships
  has_many :groups, :through => :memberships
end 

class Group < ActiveRecord::Base 
  has_many :memberships 
  has_many :members, :through => :memberships
end 

class Connection < ActiveRecord::Base 
  belongs_to :person 
  belongs_to :contact, :class_name => "Person", :foreign_key => "contact_id" 

  named_scope :accepted, :conditions => ["status = ?", Connection::ACCEPTED] 
end 

class Membership < ActiveRecord::Base 
  belongs_to :person 
  belongs_to :group 

  named_scope :accepted, :conditions => ["status = ?", Membership::ACCEPTED] 
end 

# controller
# get person's accepted contacts
@person = Person.first
@person.connections.accepted.map(&:contact)

# get group's accepted members
@group = Group.first
@group.memberships.accepted.map(&:person)
于 2010-06-13T14:47:23.047 回答
0

你是在自问自答:

named_scopes 不应该在 Membership 和 Connection 类中吗?

是的,他们应该是。这将使您可以随心所欲地调用它们。从逻辑上讲,这也是他们所属的地方。

如果您想在 Person 上同时检查两者,您可以执行以下操作:

named_scope :accepted, :conditions => ["connections.status = ? OR memberships.status = ?", Connection::ACCEPTED, Membership::ACCEPTED]

也许你希望这是一个 AND?没有把握。

于 2010-06-13T02:19:58.210 回答