编辑 - 我改变了面向对象的建模,以更好地反映我的应用中不那么特别直观的关系,(谢谢,Anthony),这样这个问题就更有意义了。对此感到抱歉。
在我的Rails应用程序中,我希望某些模型能够不仅在实例级别而且在类/关系级别上委托给其他模型。也就是说,假设House
模型,has_many
Users
并定义了类级方法" addresses
"这是houses
的关系,我可以这样做:
users.addresses
在幕后,这实际上会做两件事:1)运行users.houses
(这将抓住所有带有ID的房屋,其中包括从用户关系的house_id
列中提取的房屋),以及2)在房屋关系上打电话addresses
。
我的尝试目前看起来像这样:
class House
has_many :users
def self.addresses
map(&:address)
end
def address
"#{street_address}, {state}, #{country}"
end
end
class User
belongs_to :house
delegate :address, to: :house
class << self
delegate :addresses, to: :houses
end
def self.houses
Houses.where(id: pluck(:house_id))
end
...
end
这基本上似乎有效 - 差不多。如果我有一组用户,我可以执行users.houses
并获取houses
的关联关系。如果我在addresses
的无关关系上调用houses
,则该方法效果很好。如果我拨打users.addresses
,则会在houses.rb
中调用该名称的类级方法。
但是,当我尝试将这些内容链接在一起时,方法会出错。
如果我致电users.addresses
(或users.houses.addresses
,因此委托本身不是问题),则调用House.addresses
方法,但在该方法中,{{ 1}}似乎不是self
应该(通常会)返回的房屋的关系,而只是House类本身。因此,如果我在users.houses
self
内调用任何数组方法(这将对某个关系起作用),则该方法会抛出错误,例如addresses
。
即使我拿走了我喜欢的类级别委托逻辑并将其替换为显式版本,这个问题仍然存在:
undefined method 'map' for <Class:0x1230101239123>
同样的错误。我刚刚尝试class User
...
def self.addresses
houses.addresses
end
end
。
执行的唯一版本如下:
users.houses.addresses
换句话说,逻辑链似乎是相同的,但是将class User
...
def self.addresses
houses.map(&:address)
end
end
移动到map
方法中并移出User
方法可以解决问题。
我对此非常困惑,因为在我看来,最后(成功)版本应该基本上与上面两个失败的版本相同。唯一的区别是,在成功的版本中,我以一种我想避免的方式重复逻辑。
所以我猜问题是
1)为什么House
会返回关系,但users.houses
(和users.addresses
)突然在课堂上调用users.houses.addresses
而不是关系?
2)鉴于这些问题,是否有更好的,更多Railsy方式来设置House和User之间的关系,以便我可以运行这些类级别的查询方法(即{ {1}})?
关于解决这个问题的最佳方法的任何意见?