方法应该去哪里(模型?,其他地方)

Where should method go (model?, somewhere else)

我的一个模型中有一个方法,其中 returns 数据将被输入图表 gem。

class MyModel < ActiveRecord::Base
  def ownership_data
        format_data(item_ownerships.group(:owned).count)
  end
end

我需要保证数据 return 在结果中总是有 2 个值。像这样:

{ "yes" => 4, "no" => 2 }

为了做到这一点,我编写了第一种方法中使用的另一种方法:

def format_data(values)
   values[false].nil? ? values = values.merge({ "no" => 0 }) : true
   values[true].nil? ? values = values.merge({ "yes" => 0 }) : true

   return values
end

我的问题是,这个方法应该去哪里?我如何使用 rspec 对其进行单元测试?我目前已经在模型中得到它,但是在尝试使用 rspec 对其进行测试时,我的规格如下所示:

let(:values) { { "yes" =>2 } }

it "it will return 2 values" do
    result = MyModel.new.format_data(values)
    expect(result.keys.count).to eq(2)
end

我不太高兴必须实例化模型的实例来测试它。任何指导表示赞赏。

正如 AJ 在评论中提到的,我们可能需要更多信息才能继续提供更具体的建议。无论如何我都会给一些...

如果您有一个不一定依赖于模型本身的对象,您应该考虑将其移至 plain old ruby object or a service object。这些可以存在于单独的文件夹 (lib/services) 中或模型文件夹中而不继承自 ActiveRecord::Base

您的方法也可以是 class 方法 def self.method_name(values, values_2) 而不是实例方法(如果您不需要模型中的特定值)。

当涉及到为我的项目报告的数据操作时,我为 'lib/reports' 下的对象构建了 ruby 服务对象的特定文件夹,它们获取原始数据(通常在 init 方法中)和 return 来自方法调用的格式化数据(如果可以在不同的输出选项中格式化相同的数据,则允许我进行多次调用)。这使它们与模型分离。此外,这使测试变得容易(在 Class.new 中传递已知值,期望方法输出中的特定值。