Ruby委托类/关系级方法

时间:2015-01-07 21:18:18

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

编辑 - 我改变了面向对象的建模,以更好地反映我的应用中不那么特别直观的关系,(谢谢,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}})?

关于解决这个问题的最佳方法的任何意见?

0 个答案:

没有答案