Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Saturday, January 23, 2016

guidelines for where to put classes in Rails apps that don't fit anywhere

guidelines for where to put classes in Rails apps that don't fit anywhere


I'm wondering if there are any best practices about where to put non-standard Ruby files in Rails apps, those that don't fit in any of the default directories (controllers/models etc.).

I'm talking about classes that are used by controllers/models etc., but are not subclasses of any of the Rails base classes. Classes that include functionality extracted from models to make them less fat. Some of them kind of look like models but aren't AR models, some of them look more like "services", some are something in between or something else.

A few random examples:

  • "strategy" classes that handle authentication with password, via facebook etc.
  • "XParams" objects that encapsulate params or "XCreator" objects that handle processing of params to execute some complex action that results in creating some AR models in the end
  • classes that make requests to external APIs or encapsulate those requests and responses
  • fake models that can be substituted for a real AR model (e.g. guest user)
  • Resque jobs
  • classes that store and read information from Redis
  • classes that execute some specific actions like processing data, generating reports etc. and are called from Resque jobs or rake tasks

I've got quite a lot of these now, some of them are added to lib which ends up as a pile of random classes and modules, some sneak into app/models. I'd like to organize this somehow, but I don't know where to start.

Should only AR models go into app/models? Or is it ok to also put there any domain or helper models? How you decide if something is a model?

Should everything that doesn't fit into app go into lib? Or maybe I should add a few new custom subdirectories to app? What subdirectories, and how do I divide the custom classes?

How do you handle this in your projects? I know every project is a bit different, but there must be some similarities.

Answer by Richard Brown for guidelines for where to put classes in Rails apps that don't fit anywhere


I place any model classes (like STI subclasses) in apps/models. I place my other classes in lib, as it seems to be the best place to put them. It's easy for me to know where to look. It's also easier for me to group my tests since my model classes are all in one place.

Convention-wise I'm loathe to put helper classes in app/models. If they're presenter classes they belong in the app/helpers. If they're not then lib seems to be the best place for them.

Answer by cfeduke for guidelines for where to put classes in Rails apps that don't fit anywhere


Often my classes find their way into lib in subdirectories where modules with the same name as the subdirectory is responsible for including them. (Rails is very touchy about filenames and classnames when it comes to the autoloader.)

Another option is to encapsulate each module into its own gem and then refer to the gem via your Gemfile. This permits code sharing across projects.

Answer by Dave S. for guidelines for where to put classes in Rails apps that don't fit anywhere


You touch on a number of different use cases, and I think that this part is the closest to the "right" answer:

I've got quite a lot of these now, some of them are added to lib which ends up as a pile of random classes and modules, some sneak into app/models. I'd like to organize this somehow, but I don't know where to start.

That's pretty much right on in my book. The one thing you don't mention is extracting various pieces into separate gems. Classes that talk to external services are excellent candidates for extraction, as are strategy classes if they're sufficiently general. These can be private, since running your own gem server isn't hard, and you can then obviously reuse them across ROR apps.

Last and most concretely, resque jobs I stuff into lib/jobs.

My rule of thumb is if it's a model of some kind, it goes into app/models. If not, it probably belongs in lib or some appropriately named subdirectory thereof, e.g. lib/jobs, lib/extensions, lib/external, or the like.

Answer by house9 for guidelines for where to put classes in Rails apps that don't fit anywhere


Good question - i don't have a concrete answer for you

but I recommend checking out this post - http://blog.codeclimate.com/blog/2012/02/07/what-code-goes-in-the-lib-directory/ - be sure to read through all the comments

on a current project i have a ton of non-ActiveRecord objects under app/models, it works but not ideal i put 're-useable' non application specific code under lib

other alternatives I have tried on side projects (say we have a bunch of command objects) rails is a pain when it comes to namespaces under app, it loads everything up into the same namespace by default

app/    commands/      products/create_command.rb         # Products::CreateCommand      products/update_price_command.rb   # Products::UpdatePriceCommand  

alternate, everything besides rails under src or an app_name directory

app/    src/      commands/        create_product.rb         # Commands::CreateProduct        update_product_price.rb   # Commands::UpdateProductPrice  

I haven't come across a good solution for this, ideally the 2nd one is better, but would be nice to not have the additional directory under app, that way you open app and see controllers, commands, models etc...

Answer by Kuba Suder for guidelines for where to put classes in Rails apps that don't fit anywhere


If you're interested, I also wrote a follow-up article about this a bit later summing up what I found: http://blog.lunarlogic.io/2013/declutter-lib-directory/


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.