How can I modulate a Rails model?

I am implementing several classes that have no data per se, just logic. These classes implement today's access control policy, which depends on several parameters taken from other models.

First, I try to find an answer to the question: "Where to store such classes?" here and the answer was apps/models

. This is fine, but I like to clearly separate these classes from the inherited ActiveRecord classes in a hierarchy, both in the file and in the class.

So I created classes inside a module Logic

like Logic::EvaluationLogic

or Logic::PhaseLogic

. I also wanted to have constants that passed between these logics. I prefer to place these constants in a module Logic

. Thus, I did the following:

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

  class PhaseLogic
    def self.some_phase_control_code

# in logic/evaluation_logic.rb
module Logic
  class EvaluationLogic
    def self.some_other_code


Now it works fine with rspec

(it passes tests I wrote without issue) but not with the development server as it cannot find the constant Logic::PHASE_INITIAL


I suspect it has something to do with a mismatch between the Rails autoloading schema and what I wanted to do. I tried to set up rails but with no luck ended up canceling the wrapper module Logic


Now the question I want to ask is, how can I organize these classes using Rails? I am currently using 3.2.1.

Posted the next question " How can I organize the class namespace in applications / modules with rails? "


source to share

2 answers

I'm not sure if I really understand your classes, but could you create a module Logic

or (I would rather do this :) PhaseLogic

and EvaluationLogic

objects in the directory/lib

It is not said that Model is always a descendant of ActiveRecord. If the object belongs to "business logic", then it is a model. You might have models that don't touch the database in any way. So, if your classes are "business objects", put them in "application / models" and use like any other model.

Another question is whether to use inheritance or modules , but I'd rather think about including a module in PhaseLogic

rather than defining PhaseLogic

in a module. Of course, this all strongly depends on the intended role of your objects.

Because in Ruby the class of an object is not important, you don't need to use inheritance. If you want to "connect" logical objects to other objects, just make sure that all "* Logic" classes have the required methods. I know that everything I've said is very vague, but I think I cannot give you more specific suggestions without knowing more about the role of these objects.

Oh, and one more thing!

If you come across autoloading Rails class, just use the old one require "lib/logic.rb"

in all classes where you use constants Logic::PHASE_INITIAL


In this case, I am assuming that your problem was caused by a different boot order. logic/evaluation_logic.rb

loaded up to logic/phase_logic.rb

. The problem can go away if you create logic.rb

somewhere where class autoloading can find it and define these constants in this file.



Do not Logic

name your classes or modules using specific names. Start by extracting the logic into separate classes and then try to break them down into smaller ones. Use namespaces to distinguish them from each other in a folder lib

, after these steps you could extract some logical pieces to separate gems and reduce code level and application complexity. Also consider template presenter .



All Articles