Rails 3.2.1 models in modules - ruby-on-rails

I have many models in my applications and some of them are closely related to each other so I decided to group them up and make modules.
Here is what I did as an example: http://pastebin.com/qqELTd2k
Now I am curious about three things.
Firstly: do I realy need to specify the module name in relationships, if they do not go outside the module (e.g. the 'belongs_to :status' association in the paste) or it should work withought it properly (I do have a model called Status in the root model directory and it is different from Qna::Status).
Secondly: will that :char association work properly, going outside the Qna module?
Third: Is it a good idea at all to group models like that? It makes the models directory much cleaner, but I am not sure about the common conventions.
UPDATE
4th: can I put the qna.rb file discribing the module in the qna folder in app/models? And if yes, what modifications do I need to do (obviously it does not go that easy).

Related

About location of strategy pattern in rails

I am implementing strategy pattern in Rails where I have Models like User, Item, Category and need to recommend items for the users depending on various algorithms (strategies) that user selects in view.
I am having a Recommend class which has an interface of recommend(user_id, strategy) and returns array of item_id. The strategy in recommend will be decided at runtime depending on the option user selects in the view. I have placed the recommend interface in /lib directory and the strategies in /lib/strategy directory.
I want to make sure if I placed the files in proper directories or Should I need place the recommend class and all the strategies in models or any where else. I am really confused.
In Rails all domain-specific code belongs in /app, whereas /lib is reserved for external dependencies and shared code.
You might find "service objects" useful, they belong in /app/services. They are not ActiveRecord classes and have no database, they generally work (perform services) with other models.
You'll find lots of info on how to construct services e.g. http://sporto.github.io/blog/2012/11/15/a-pattern-for-service-objects-in-rails/. There is also an excellent Railscast (subscribers only) http://railscasts.com/episodes/398-service-objects.

Where do I put my helpers and how do I test them?

This is my first on StackOverflow and I'm a new rails developer.
I'm using RoR to create an inventory application for Magic: The Gathering cards. I've found a Json API that I'd like to use to pull data on all of the cards, sets, etc into a local database.
My initial inclination is to create a helper class to manage all of this (which can also be called in seeds.rb during db:setup), but I have no idea where I should put this class in my project's directory structure. It's not really a model/controller/view, so I feel it should be kept separate from those parts of the app.
Further more, I'm having trouble testing any class I do make. I initially created a directory app/classes and put the class there. Then in my spec directory, I created spec/classes and created the spec file. Accessing my helper class from the spec did not work in the same way that accessing my models in their spec classes did.
I'm at a loss as to how to do this and quite a bit of googling and searching on here has just left me more confused. I'd love any help that can be offered. How would you do this?
You don't mention specifically what issues you're encountering, but for starters app/classes isn't in rails's autoload path - rails' require magic doesn't know to look in there to find these classes (as an aside, 'classes' sounds like a slightly meaningless name - models & controllers are classes too).
You can add to the paths rails searches (see config.autoload_paths in config/application.rb) but I would put this in lib (and the corresponding specs in spec/lib).
It would also work just fine with these classes in app/models, whether or not it does there is down to choice. There's nothing that says that files in there have to be active record subclasses - the decision of whether or not this functionality belongs in there boils down to whether it works/feels like a model to you.

Sharing AR models between Rails applications

I have a problem that I have been trying to solve for a while now. I have 4 different Rails applications using the same database, meaning they need to use the same models and have the same migrations. I initially solved the problem by creating a Rails engine packaged into a gem, which then carries all the models and migrations with it. Now I realize that there are pieces of functionality that only one application needs, but the others do not - like for example the admin application needs to have methods for providing sortable tables for all models - the other applications do not need this functionality at all.
So my idea was to find a way where I can provide the "base" models from the gem, while augmenting these base models in my specific applications to add additional functionality when needed. What I tried first was inheritance:
class User < Base::User
end
This does not work though, because now you have 2 User models in your load path (User and Base::User) and when querying associations, it always picks the "closest" class for the associated record class - meaning when you have an Model::Account which belongs_to :user, it will pick Model::User as the association class, not User. I tried reversing the AR type compute method but this only resulted in more problems.
I can technically provide all of my models from the base engine (gem), but the issue here is that how do i extend these models in my application? .class_eval feels really really dirty, inheritance does not work, providing base functionality as mixins means the "base" models do not feel and look like models at all. My goal would be to cause as little friction as possible for the other developers, I want them to be able to define their models in the gem like they do normally and then also have an easy way to extend that functionality in other applications.
Has anyone solved this problem before or have any suggestions? Or how do you guys solve this problem in your larger applications? Any help would be appreciated.
This is mentioned in the Rails guides. It describes class modification with the Decorator pattern.

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.
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...
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.
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/
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.
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.

Namespaced models in Rails: What's the state of the union?

Since the beginning, Rails has had issues with namespaced models. As time went on, pretty much everybody gave up on using it. Myself included.
With Rails 2.3 out, I'd like an update on the situation. Specifics questions I have in mind are:
first off, is it good to go?
table naming, what rule to follow?
associations, how to declare them with the least verbosity? how to name foreign key columns?
auto-requiring, does it work if you put the model files in a subdir matching the namespace? or, how to name and where to place the files?
generation, does the model generator handles namespaces successfully and correctly?
generation, how about the scaffold generator, which includes controllers?
any incompatibilities/quirkinesses one should be aware of?
The best writeup I've seen on the issue is from Strictly Untyped. To my knowledge 2.3 hasn't resolved any issues, which means they're still unreliable.
We recently had a big debate about this inside our company. I think at the end of the day, we figured that if you can't namespace tables inside a database, it makes no sense to namespace the models. We settled on prefixing our models (User, UserAddress, UserEmailAddresses) and putting them into the users directory, then using:
config.load_paths << "#{RAILS_ROOT}/app/models/users"
to load the models. To control the verbosity in our models, we do this frequently:
has_many :addresses, :class_name => "UserAddress"
When generating, we create it as if there was no namespace (script/generate model UserAddress) then manually copy it to the user directory.
Shrug. I guess in the end all this really gives you is a cleaner directory structure, which is actually more trouble for a VIM user like me, but nice for TextMaters.
I would still stay away from it. Anything gained (which I'm not sure what that would honestly be) would definitely be lost when you consider the hassle and loss of brevity and clarity in your code.
My latest app has 87 resources, and includes administrative features all over the place. I see no need for namespacing, IMHO.

Resources