How can I organize the namespace of the classes in applications / modules with rails?

[This is the next question to How can I modulate a Rails model? "]

Do I even need to organize classes in the app/models

Rails directory ? Should I use one top namespace for all classes?

The initial motivation is that I want to host business logic classes that are not inherited from ActiveRecord::Base

into the directory app/models

. A search on this site reveals many answers that recommend placing business logic classes in a directory app/models

. I posted another question and got a recommendation that such classes can be placed in a directory lib


Now I'm curious. I would like to put these classes in a different namespace and directory in the directory apps/models

recommended by others. Is it possible?

Actually, I am experimenting with this, but it seems to me that this is something that rails are not expected. If I create a class like this (like SomeModName :: ClassInMod in some_mod_name / class_in_mod.rb) it doesn't load. Also, I have defined constants inside the module. Since they are not loaded, I cannot use them. In fact, rspec

it works with no problems, but the rails server

class is not loaded. I'm pretty sure it has to do with an autoload issue.

In addition to the classes mentioned above, classes inherited from ActiveRecord::Base

can be placed in some namespaces internally module

. I'm curious if this works well or not.

So the question in other words: can I make the rails happy by configuring these files to load or not the way the rails were designed?


source to share

1 answer

Yes, you can define an ActiveRecord class in a module. The easy way is to use a generator:

./script/rails generate model logic/phase_logic
./script/rails generate model logic/evaluation_logic


Note that Rails will additionally create a module definition file. In this case:

# app/models/logic.rb
module Logic

# app/models/logic/phase_logics.rb
class Logic::PhaseLogic < ActiveRecord::Base

# app/models/logic/evaluation_logics.rb
class Logic::EvaluationLogic < ActiveRecord::Base


Your problems with the constants defined in the module were caused by the fact that you defined the constants in the definition module, wrapped around only one of the two models you created. A very important role in understanding ruby ​​(and Rails) - especially for people with strong experience with compiled languages ​​- is to remember that there is no compilation phase , so the definition of a certain class is read and executed only when that particular class is used. Sometimes a week after starting the application server and serving thousands of requests.

So, as I said in my answer to the previous question , the problem with autoloading was that sometimes the definition of constants was read after the definition that tried to use them. The order was random - if the first object used was EvaluationLogic, then an error was thrown. This is the first object that happened to be PhaseLogic, everything was fine.

Now that you have a file for the module itself and define the constants in that file ( app/models/logic.rb

), autoloader can find and execute the definitions before any class starts using them. I hope all will be ok.



All Articles