Ruby 如何将Rails模型模块化?
我正在实现几个类,它们本身没有数据,只有逻辑。这些类实现了迄今为止的访问控制策略,这取决于从其他模型的数据中获取的几个参数 我最初试图在这里找到“在哪里存储此类类?”的答案,答案是Ruby 如何将Rails模型模块化?,ruby,ruby-on-rails-3,Ruby,Ruby On Rails 3,我正在实现几个类,它们本身没有数据,只有逻辑。这些类实现了迄今为止的访问控制策略,这取决于从其他模型的数据中获取的几个参数 我最初试图在这里找到“在哪里存储此类类?”的答案,答案是apps/modelsdirectory。这没关系,但我喜欢在层次结构中将这些类与ActiveRecord继承的类明确分开,包括文件类和类 因此,我在Logic模块中创建了类,比如Logic::EvaluationLogic或Logic::PhaseLogic。我还想要在这些逻辑之间传递常数。我更喜欢将这些常量也放入逻
apps/models
directory。这没关系,但我喜欢在层次结构中将这些类与ActiveRecord继承的类明确分开,包括文件类和类
因此,我在Logic
模块中创建了类,比如Logic::EvaluationLogic
或Logic::PhaseLogic
。我还想要在这些逻辑之间传递常数。我更喜欢将这些常量也放入逻辑
模块中。因此,我实现如下:
# 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
上运行得很好(它通过了我编写的测试,没有问题),但在development server上却不行,因为它找不到Logic::PHASE_INITIAL
常量
我怀疑这与Rails的自动加载方案不匹配以及我想做的事情有关。我试图调整rails,但没有成功,最终取消了模块逻辑
wrap
现在我想问的问题是:如何使用Rails组织这些类?
我现在正在使用3.2.1
发布了一个后续问题“我不确定我是否真的理解了你的类,但是你不能创建一个
逻辑
模块,或者(我更愿意这样做:)阶段逻辑
和评估逻辑
对象,在/lib
目录中
并不是说“模型”总是ActiveRecord的后代。如果对象属于“业务逻辑”,那么它就是一个模型。您可以拥有不以任何方式接触数据库的模型。因此,如果您的类是“业务对象”,请将它们放在“应用程序/模型”中,并像其他模型一样使用
另一个问题是您是否应该使用继承还是模块——但我更愿意考虑在PhaseLogic
中包含模块,而不是在模块中定义PhaseLogic
。当然,所有这些在很大程度上取决于对象的预期角色
因为在Ruby中对象类并不重要,所以不需要使用继承。如果要将逻辑对象“插入”到其他对象中,只需注意所有“*logic”类都具有所需的方法。我知道我所说的一切都很模糊,但我想如果我不了解这些物体的作用,我就不能给你一些更具体的建议
啊,还有一件事
如果您发现自己在使用Rails类自动加载,只需在使用logic::PHASE_INITIAL
常量的所有类中使用旧的require“lib/logic.rb”
在这种情况下,我想您的问题是由不同的装载顺序引起的。
logic/evaluation\u logic.rb
已在logic/phase\u logic.rb
之前加载。如果您在自动加载类可以找到的地方创建logic.rb
,并在该文件中定义这些常量,则问题可能会消失。不要命名类或模块logic
使用特定名称。从将逻辑提取到单独的类开始,然后尝试将它们分解成更小的类。在lib
文件夹中使用名称空间来区分它们,完成这些步骤后,您将能够提取一些逻辑部分来分离gem,并降低代码库和应用程序的复杂性。还可以查看模式。可能在lib/logic/
中,并在相关模型中包含/扩展?您还可以使用config.autoload_paths+=“{config.root}/where____想_放置_逻辑_类”config/application.rb
中的
完全不必使用require
。我意识到我把两个问题混为一谈了。我最初的想法是按照您的建议将此类类放入lib
。但是我觉得把这样的东西放到库中有点尴尬。我试图在Stackoverflow中找到推荐,发现大多数人建议将其放入模型中。如何设计这些类是不同的问题,我还没有很好地描述为什么我要上这门课。我的意图是我想实现两种相互作用的逻辑,所以将它们放在一个名称空间中似乎是合理的,所以高于结构。(con't)和模块的使用风格,出于这个目的,我更喜欢我的方案,因为我想将逻辑封装到类中,不想污染引用模块的类(包括它)。这部分是因为我还不习惯Ruby的混合方式(我使用C++太长:20年),也注意到,正如Frost推荐的,使用AutoLoad路径来代替<代码> App似乎是自然的。我可以用这个方案来解决问题,但我将发布另一个问题无论如何,感谢您的回答/评论。我正在使用模块
进行名称空间分离。除了模块
,您如何区分名称空间?