Ruby on rails 3 委托或实例化其他类?

Ruby on rails 3 委托或实例化其他类?,ruby-on-rails-3,refactoring,delegation,Ruby On Rails 3,Refactoring,Delegation,假设我有一个Account类和一个AccountReport类。在accounts#show中,我想显示一个帐户的报告。Account和AccountReport都有许多公共方法。以下哪种技术更好 1) 实例化帐户和AccountReport,使用帐户数据初始化AccountReport class AccountsController < ActionController::Base def show @account = current_user.account @

假设我有一个Account类和一个AccountReport类。在accounts#show中,我想显示一个帐户的报告。Account和AccountReport都有许多公共方法。以下哪种技术更好

1) 实例化帐户和AccountReport,使用帐户数据初始化AccountReport

class AccountsController < ActionController::Base
  def show
    @account = current_user.account
    @account_report = AccountReport.new(@account.orders)

    respond_with(@account)
  end

  # ...
end
class AccountsController
2) 允许Account实例实例化AccountReport和委托方法调用

class Account < ActiveRecord::Base
  attr_reader :account_report

  delegate :method_a, :method_b, :method_c, :method_d, :to => :account_report

  after_initialize :setup_account_report

  def setup_account_report
    @account_report = AccountReport.new(orders)
  end

  # ...
end
类帐户:账户报告
初始化后:设置帐户报告
def设置帐户报告
@account\u report=AccountReport.new(新订单)
结束
# ...
结束

选项2对我来说似乎是一种更为简洁的方法,但使用大量的方法加载Account会让它感觉像一个神的类。

好吧,我认为您必须将这两种方法混合使用

第一个是好的,如果你只在节目中使用报告的话。 第二个是好的,如果你使用所有的时间报告为您的帐户

对于第二个,您的报表将一直被实例化,这可能会降低性能

您或许应该尝试以下方式:

class Account < ActiveRecord::Base
  # ...

  @report = nil
  def report
    if @report.nil?
       @report = AccountReport.new(self.orders)
    end
  end

  # ...
end

我喜欢第一个选项,因为它保持低耦合。第二个选项将Account和AccountReport以一种可能不必要的方式联系在一起。当你收到另一种类型的报告时会发生什么?您可能需要更改帐户中的一系列内容,这是令人伤心的,因为它们似乎不相关

通过在服务对象中组合这两件事,并将其交给视图,可以在控制器中保持较低的逻辑/详细性。
AccountReporting
服务可以处理将这两个类组合在一起的逻辑,例如:

class AccountReporting
    def initialize(account)
       @account = account
    end
    def report
       AccountReport.new(account.orders)
    end
end
然后,要在控制器中使用它:

AccountReporting.new(current_user.account)

这有意义吗?

我想我明白了。我喜欢懒洋洋地加载报告的想法。有没有可能以这种方式委托给AccountReport/Report,或者我需要使用方法链接account.Report.total来使用这种方法?
@Report | |=AccountReport.new(self.orders)
是一个很好的比喻,说明了您正在尝试上述操作。谢谢!我把这两条建议结合起来,效果很好。我甩了我的阅读器,写了一个方法来获取报告,然后返回或初始化它。我知道这在哪里有用。我认为对于经常使用的类,我可以使用改进版的方法#2,对于不经常使用的类,我可以使用这种方法(改进的#1)。你说得对,我要上几种这样的课。我正试图缩减我的应用程序的两个God类,以实现更好的SRP/解耦。
AccountReporting.new(current_user.account)