红宝石委托类/关系级别的方法(Ruby delegating class/relation-leve

2019-10-21 13:20发布

编辑 - 我改变了面向对象的建模,以更好地反映在我的应用程序的未特别直观的关系,(感谢,安东尼),因此,这个问题更有意义。 对于那个很抱歉。

在我的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方法被调用,但该方法中, self似乎是房子是不是关系 users.houses应该(和一般不)的回报,但只是众议院类本身。 因此,如果我请任何阵列方法selfaddresses (这将在关系工作),则该方法将引发错误如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

换言之,逻辑链似乎是相同的,但在移动mapUser的方法和流出的House方法固定的东西。

我对这个超级困惑,因为我的眼睛,那最后的(成功的)版本应该从根本上等同于上述两个版本的失败。 唯一的区别是,在成功的版本,我在我想避免的方式重复的逻辑。

所以我想的问题是

  • 1)为什么users.houses返回一个关系,但users.addresses (和users.houses.addresses )突然调用addresses的类,而不是有什么关系?

  • 2)考虑到这些问题,有没有建立,这样我可以运行这些类级的查询方法众议院和用户之间的关系更好,更Railsy方式(即users.houses )?

的最佳方式任何意见去修复呢?

文章来源: Ruby delegating class/relation-level methods