Ruby委托类/关系级方法
编辑 – 我改变了面向对象的建模,以更好地反映我的应用程序中非特别直观的关系,(谢谢,安东尼),这样这个问题更有意义。 对于那个很抱歉。
在我的Rails应用程序中,我希望某些模型能够不仅在实例级别而且在类/关系级别上委托给其他模型。 也就是说,假设一个House
模型,它具有多个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
关系。 如果我在不相关的houses
关系上打电话给addresses
,那么该方法效果很好。 如果我调用users.addresses
,它会在users.addresses
调用该名称的类级方法。
但是 ,当我尝试将这些东西链接在一起时,方法会出错。
如果我调用users.addresses
(或users.houses.addresses
,所以委托本身不是问题),调用House.addresses
方法,但在该方法中, self
似乎不是users.houses
的房屋关系 users.houses
应该(并且通常会)返回,但只是House类本身。 因此,如果我在addresses
内调用self
上的任何数组方法(这将对某个关系起作用),该方法会抛出一个错误,例如undefined method 'map' for
。
即使我拿走了我喜欢的类级别委托逻辑并将其替换为显式版本,这个问题仍然存在:
class User ... def self.addresses houses.addresses end end
同样的错误。 当我只是尝试users.houses.addresses
。
唯一可行的版本如下:
class User ... def self.addresses houses.map(&:address) end end
换句话说,逻辑链似乎是相同的,但是将map
移动到User
方法中并且从House
方法中移出来修复事物。
我对此非常困惑,因为在我看来,最后(成功)版本应该基本上与上面两个失败的版本相同。 唯一的区别是,在成功的版本中,我以一种我想避免的方式重复逻辑。
所以我想问题是
-
1)为什么
users.houses
返回一个关系,但users.addresses
(和users.houses.addresses
)突然调用类而不是关系上的addresses
? -
2)鉴于这些问题,是否有更好的,更Railsy方式来建立House和User之间的关系,这样我就可以运行这些类级别的查询方法(即
users.houses
)?
有关解决此问题的最佳方法的任何意见?
- Rails 4嵌套属性和has_many:通过表单中的associaton
- 如何在非rails应用程序中使用ActiveRecord创建新的MySQL数据库?
- 哪个create / create_record在ActiveRecord中消失了?
- 如何为Rails Association :: Preloader设置预加载范围?
- 使用define_method动态定义的setter方法?
- Rails:ActiveRecord db排序操作不区分大小写
- Rails:将加密数据存储在数据库中
- Rails – 活动记录:查找所有记录与某些属性has_many关联的记录
- Has_many通过:关联不在Rails 5.2中注册