【发布时间】:2010-10-27 23:29:46
【问题描述】:
业务逻辑是这样的:用户通过一个连接表在一条船上,我想我们称该模型为 Ticket。但是当一个用户实例想要检查船上还有谁时,有一个条件会询问该用户是否有权看到船上的每个人,或者只是船上的某些人。如果用户可以看到所有人,则正常交易很好:some_user.boats.first.users 返回所有用户并获得该船的船票。但是对于某些用户来说,船上唯一的人(就他们而言)是在餐厅里的人。因此,如果用户的票被“标记”(使用acts_as_taggable 样式系统)带有“餐厅”,则从some_user.boats.first.users 返回的唯一用户应该是带有标记为“餐厅”的票的用户。
为了记录,我并不是想从一开始就设计一些疯狂的东西 - 我试图将这种任意分组楔入(大部分)现有系统中。 所以我们有:
class User
has_many :tickets
has_many :boats, :through => :tickets
end
class Ticket
belongs_to :user
belongs_to :boat
end
class Boat
has_many :tickets
has_many :users, :through => :tickets
end
最初,我认为我可以有条件地修改虚拟类,例如:
singleton = class << a_user_instance ; self ; end
singleton.class_eval(<<-code
has_many :tickets, :include => :tags, :conditions => ['tags.id in (?)', [#{tag_ids.to_s(:db)}]]
code
)
这一直到生成 SQL,但是在生成时,它生成的 SQL 结尾为:
LEFT OUTER JOIN "tags" ON ("tags"."id" = "taggings"."tag_id") WHERE ("tickets"._id = 1069416589 AND (tags.id in (5001,4502)))
我已经尝试挖掘 ActiveRecord 代码,但我找不到任何地方会在上面的 SQL 中以下划线为前缀的“id”。我知道加载 ActiveRecord 类时会加载关联,并且我会假设与单例类相同。 耸耸肩。
我还使用了alias_method_chain,例如:
singleton = class << a_user_instance ; self ; end
singleton.class_eval(<<-code
def tickets_with_tag_filtering
tags = Tag.find(etc, etc)
tickets_without_tag_filtering.scoped(:include => :tags, :conditions => {:'tags.id' => tags})
end
alias_method_chain :tickets, :tag_filtering
code
)
但是,虽然这种方法会产生所需的票证,但这些票证上的任何连接都使用类中的条件,而不是虚拟类。 some_user.boats.first.users 返回所有用户。
任何类型的评论都会受到赞赏,特别是如果我用这种方法吠叫错误的树。谢谢!
【问题讨论】:
标签: ruby-on-rails ruby activerecord