Rails服务对象返回'没有方法错误'

时间:2014-12-09 19:50:41

标签: ruby-on-rails ruby service-object

开始:这是我第一次尝试将业务逻辑从模型/控制器空间中取出。这是我想要抽象的一些初始逻辑。路径为app/services/Date_calc.rb

class Date_calc
  require User
  require Report

  def months(range)
    User.first.reports.order("report_month desc").limit(range).pluck(:report_month)
  end
end

在我的应用程序中,我有两个模型,User和Reports。用户has_many报告。 reports表有一个名为report_month的字段。

在Rails控制台中调用Date_calc.months(6)将返回:TypeError: no implicit conversion of Class into String

我的回应是一系列日期,例如["01/01/2013", "01/02/2013", "01/03/2013", ... ]

我不确定我在这里做错了什么。

2 个答案:

答案 0 :(得分:3)

问题在于require需要一个字符串(例如require "path_to_module"),但您要给它一个类:

require User
require Report

如果这是在Rails中运行,那么Rails将自动加载这两个类。您根本不需要require

修改:删除这些行后,Date_calc.months(6)仍然会给你一个NoMethodError,因为months是一个实例方法,但你&# 39;重新尝试将其称为“类方法”。您需要在Date_calc类的实例上调用它,如下所示:

Date_calc.new.months(6)

或者,您可以通过def self.months(range)代替def months(range)将其定义为类方法,这样您就可以调用Date_calc.months(6)。但是你可能想要考虑Date_calc是否真的应该是一个类,或者它是否应该是一个模块。

如果您想拥有多个实例,那么它应该是一个类,就像您想要一个User实例或Report实例一样。 "用户"和"报告"都是名词,因为这个类代表了一个的东西,我们可能希望拥有多个名词。句子"我想创建一个Date_calc"合理?句子怎么样"我想创建两个Date_calcs"?如果你对两者都说“是”,那么一堂课就有意义了。

但是,如果你只想要一些相关的方法,但这并不代表的东西,那么你可能想要使用一个模块。例如,在Rails中,Rails对象不是类,它是一个模块。说"我想创建一个Rails,"是不合理的。更少"我想创建两个Rails。" Rails只是一个用于将相关方法组合在一起的模块。如果Date_calc符合该描述,则它作为模块更有意义:

module Date_calc
  def self.months(range)
    # ...
  end
end

# and then...
Date_calc.months(6)

如您所见,我们使用def self.months代替def months,因为我们希望能够在模块本身上调用该方法。

答案 1 :(得分:3)

除了缺少引号的require行之外,您还在类上调用实例方法。您需要像这样

实例化Date_calc
months = Date_calc.new.months(6)

或使其成为像这样的类方法

def self.months(range)...