如何在Rails中将参数传递给委托方法

时间:2011-09-24 05:12:40

标签: ruby-on-rails model-view-controller activemodel presenter

我希望有一个仪表板来显示多个模型的摘要,我使用Presenter实现它而没有自己的数据。我使用ActiveModel类(没有数据表):

class Dashboard
  attr_accessor :user_id
  def initialize(id)
    self.user_id = id
  end

  delegate :username, :password, :to => :user 
  delegate :address,  :to => :account
  delegate :friends,   :to => :friendship

end 

通过委托,我希望能够致电Dashboard.address并返回Account.find_by_user_id(Dashboard.user_id).address

如果Dashboard是ActiveRecord类,那么我可以声明Dashboard#belongs_to :account并且委托会自动工作(即,帐户会知道它应该从user_id等于to user_id的帐户返回地址属性在仪表板实例中)。

但Dashboard不是ActiveRecord类,因此我无法声明belongs_to。我需要另一种方法来告诉Account查找正确的记录。

有没有办法克服这个问题? (我知道我可以假装Dashboard有一个空表,或者我可以将User的实例方法重写为带参数的类方法。但这些解决方案都是黑客攻击。)

谢谢。

1 个答案:

答案 0 :(得分:13)

当您编写delegate :address, :to => :account时,这会在Dashboard上创建一个新的address方法,该方法基本上调用同一对象上的account方法,然后调用address上的结果这个account方法。这(非常粗略地)类似于写作:

class Dashboard
 ...
  def address
    self.account.address
  end
 ...
end

使用您当前的课程,您所要做的就是创建一个account方法,该方法会返回具有正确user_id的帐户:

class Dashboard
  attr_accessor :user_id
  def initialize(id)
    self.user_id = id
  end

  delegate :username, :password, :to => :user 
  delegate :address,  :to => :account
  delegate :friends,   :to => :friendship

  def account
    @account ||= Account.find_by_user_id(self.user_id)
  end
end

这将允许您访问这样的地址:

dashboard = Dashboard.new(1)
# the following returns Account.find_by_user_id(1).address
address = dashboard.address