我如何模块化Rails模型?

时间:2012-03-14 12:26:05

标签: ruby ruby-on-rails-3

我正在实现几个本身没有数据的类,只是逻辑。这些类实现了迄今为止的访问控制策略,该策略取决于从其他模型的数据中获取的几个参数。

我最初试图找到“在哪里存储这些类?”的答案。在这里,答案是apps/models目录。没关系,但是我想清楚地将这些类与层次结构中的ActiveRecord继承类分开,包括文件和类。

因此,我在Logic模块中创建了类,如Logic::EvaluationLogicLogic::PhaseLogic。我还希望在这些逻辑之间传递常量。我更喜欢将这些常量放入Logic模块中。因此,我这样实现:

# in logic/phase_logic.rb
module Logic
  PHASE_INITIAL = 0
  PHASE_MIDDLE  = 1000

  class PhaseLogic
    def self.some_phase_control_code
    end
  end
end

# in logic/evaluation_logic.rb
module Logic
  class EvaluationLogic
    def self.some_other_code
      Logic::PhaseLogic.self.some_phase_control_code(Logic::PHASE_INITIAL)
    end
  end
end

现在,它可以正常使用rspec(它通过我编写的测试没有问题),但不能用于开发服务器,因为它找不到Logic::PHASE_INITIAL常量。

我怀疑它与Rails自动加载方案的不匹配以及我想要做的事情有关。我尝试调整rails,但没有运气,最终消除了module Logic换行。

现在我想问的问题是:如何使用Rails组织这些类? 我现在正在使用3.2.1。

发布了后续问题“How I can organize namespace of classes in app/modules with rails?

2 个答案:

答案 0 :(得分:1)

我不确定我是否真的了解您的课程,但是您无法创建Logic模块或(我宁愿这样做:) PhaseLogic和{ {1}} EvaluationLogic目录中的对象

并不是说“模型”总是ActiveRecord的后代。如果对象属于“业务逻辑”,那么它就是一个模型。您可以拥有不以任何方式触及数据库的模型。因此,如果您的课程是“业务对象”,请将它们放在“app / models”中,并像其他任何模型一样使用。

另一个问题是你是否应该使用继承或模块 - 但我宁愿考虑在/lib中包含一个模块,而不是在模块中定义PhaseLogic。当然,所有这些在很大程度上取决于对象的预期作用。

因为在Ruby中对象类并不重要,所以不需要使用继承。如果要将逻辑对象“插入”其他对象,请注意所有“* Logic”类都具有所需的方法。我知道我所说的一切都很模糊,但我想在不了解这些物品的作用的情况下,我不能给你一些更具体的建议。

啊,还有一件事!

如果您发现自己正在使用Rails类自动加载,只需在使用PhaseLogic常量的所有类中使用旧的require "lib/logic.rb"

在这种情况下,我认为您的问题是由不同的加载顺序引起的。 Logic::PHASE_INITIAL之前已加载logic/evaluation_logic.rb。如果您在某处创建logic/phase_logic.rb,类自动加载可以找到它,并在该文件中定义这些常量,则问题可能会消失。

答案 1 :(得分:0)

不要将您的类或模块命名为Logic使用特定名称。首先将逻辑提取到单独的类中,然后尝试将它们分解为更小的类。使用命名空间在lib文件夹中区分它们,在这些步骤之后,您将能够提取一些逻辑部分以分离gems并减少代码库和应用程序的复杂性。另请查看presenter模式。