我正在尝试通过在Rails 2.3.x中使用named_scopes来整理我的代码,但是我正在努力使用has_many:通过关联。我想知道我是否将示波器放在错误的位置......
下面是一些伪代码。问题是:接受命名的范围被复制两次......我当然可以称之为:接受不同的东西,但这些是桌面上的状态,并且将它们称为不同的东西似乎是错误的。有人能说清楚我是否正确地做了以下事情?
我知道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返回一个没有'accepted'方法的Persons数组:
>> Person.find(2).contacts.accepted
NoMethodError: undefined method `accepted' for #<Class:0x108641f28>
一种解决方案是在Person类中调用两个不同的命名范围,或者甚至创建单独的关联(即.has_many:accepted_members和has_many:accepted_contacts),但它似乎是hackish,实际上我有很多不仅仅是接受(即被禁止的成员,忽略连接,待处理,请求等)
答案 0 :(得分:0)
你回答了自己的问题:
named_scopes不应该在Membership和Connection类中吗?
是的,他们应该。这将让你按照自己的意愿打电话给他们。它在逻辑上也属于它们所属的地方。
如果你想在Person上检查两者,你可以这样做:
named_scope :accepted, :conditions => ["connections.status = ? OR memberships.status = ?", Connection::ACCEPTED, Membership::ACCEPTED]
也许您希望这是一个AND?不确定。
答案 1 :(得分:0)
我确信这不是最佳方式,我相信您可以在person
和group
型号上执行此操作,但我也相信以下内容对您有用:
# 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)