What's the difference between a controller helper and a concern? - ruby-on-rails

Would concerns help me share logic for partials? I see Rails 4 has the "concerns" folder for controllers, but it's empty on app generation.
DHH wrote a blog on concerns (but I think they are for the model): http://37signals.com/svn/posts/3372-put-chubby-models-on-a-diet-with-concerns
I would appreciate a concise example.

Simply put:
Helpers contain methods to be used in views.
Concerns are modules to be included in controllers/models(depending which concern is it) etc.
It's just a folder with code that you could otherwise put in another place if you wanted. We use fancy terms like concerns to get paid more.

Concerns are modules that get mixed into controller or model classes for instance. DHH's post focused on models, but the same applies to controllers. It helps slim down the model or controller classes, and makes it easier to reuse common code across multiple classes.
Helpers are for short presentation-oriented methods that you want to call from your views, or very occasionally from your controllers, maybe.

Related

How do Rails views get access to concerns?

I've been learning Rails and seems like concerns are a way to dry up fat models and make methods sharable by models. I'm confused though as to why views/partials have access to these methods. Shouldn't the MVC model make all the model related things go through the controller and then be given to the view. It feels like giving views access directly to model concerns skips the controller. Also why do I not have access to these methods in Rails console?
A model concern can be seen as a way to split up a model with many methods. It is possible to share common methods between models, but also possible to just thin out the model code.
Once you include the concern, all concern methods are mixed into the model, and therefore are available anywhere the 'base' model methods are.

What is the Rails Presenters folder for?

What is the Rails Presenters folder for?
What goes in this folder?
Why is this folder needed?
presenters is a design pattern commonly reffered to as Model View Presenter(MVP)
This is a derivation of the Model View Controller pattern and is used for creating user interfaces.
It's useful for the Separation of Concerns for making code more DRY.
Here's how Wikipedia describes it
model - interface defining the data to be displayed or otherwise acted upon in the user interface.
presenter - acts upon the model and the view. It retrieves data from repositories (the model), and formats it for display in the view.
view - a passive interface that displays data (the model) and routes user commands (events) to the presenter to act upon that data.
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter
Presenters in Ruby on Rails
Presenters are simple classes that sit between the model and the view and provide a nice, DRY object oriented way of working with complex display logic.
In Rails, the convention is for them to be located in the app/presenters folder
Here is a userful article that explains the pattern and its use in Ruby on Rails.
https://kpumuk.info/ruby-on-rails/simplifying-your-ruby-on-rails-code/
The Presenters folder is where your Presenter code would go. I know, obvious, I'll explain.
The way I think of Presenters and Decorators is as an abstraction of a Model in order to massage the data attributes before they are given to view.
If you are familiar with helpers, well, Presenters are kind of like helpers in the sense that they are getting some data ready for the view, except helpers usually serve as utility methods for said views, while presenters are more about presenting the actual attributes.
This link explains the difference very well: https://awead.github.io/2016/03/08/presenters/
hope that helps.
Presenters de-clutter your views
When people mention presenters in a rails context (as opposed to discussions of Model-View-Presenter, MVC, MVVM discussions etc) they are referring to a situation where things look really complex in your views: there are plenty of if statements everywhere, and it's difficult to read through it all.
Or to adopt an everyday analogy: imagine you have a really messy house, with stuff piled up everywhere - so that it's difficult to walk through. You can think of a presenter as a large garage where you can neatly organise everything. This makes it much easier to walk through your house, and you still have all the utensils that you need.
Getting back to the rails context: Presenters allow you to remove all that complex logic somewhere else: into the Presenter's folder, so that when you read your views, it will be a lot easier to understand from a higher level. The clutter isn't there, the complexity isn't there: that has been transferred somewhere else. If you want more detail, you will have to go to the relevant folder. The logic need not be contained in a folder called "Presenters" but it can be put there by convention.

Rails Controller Inheritance vs. Concerns and Mixins

I have a lot of similar resources in my Rails application, and I have currently DRY'd up the code using controller inheritance. I see that there is a directory called concerns under the controller folder, where I could potentially write similar concerns (such as archiving, activate/deactivate etc.) I can probably write mixins too.
Is there a preferred approach to DRY up the controller code? Is there any downside in using inheritance, or are there any advantages using other techniques?
Is there a preferred approach to DRY up the controller code?
In my experience, it depends on what you want the code to do. I've only used concerns for simple controller-independent methods, such as before_action or something
I would use inheritance if your controller's methods are able to rely on a super class or something. My experience so far has lead me to use inherited_resources - a DRY way to create controller inheritance

What is the best way to implement skinning in a Rails app

Using Rails, I am building several sites which are very similar. I want to implement these as one Rails app answering to multiple domains, and change what is presented and the processing logic based on the domain name. The areas I need to change/skin per site are:
Views: The fields on a page differ slightly by site. Some sites have more/different fields than others, but there are some that are common across all
Models (which seems best to do this by defining a super class for the main model which varies and implement a subcalss for each site)
Controller logic. There is a lot of similarity but a few small processing differences, including which Model subclass to deal with
CSS (which seems fairly straight forward)
I have already implemented a mechanism which makes the current domain/app name visible to the views, controllers and models.
I was thinking of defining a view partial per site and using ERB logic to include the right one. The controllers seem like the least obvious part.
Any suggestions very much appreciated.
Cheers
Paul
I have implemented something similar for our application, HiringThing (http://www.hiringthing.com)
To do so, we use a before_filter on the application controller that parses request.host and determines what website the request is for. That then sets a variable #site that we reference in views, controllers and models to determine versioning requirements at runtime.

Does this approach to fat model/skinny controller take it too far?

I am afraid that I might be getting lazy.
I am developing a ruby on rails application involving about 8 models relating to two types of users: physicians and patients. Most of the logic is inside the models allowing my controller actions to be very short and concise. Plus, it makes the testing fairly straightforward.
I currently envision at least two controllers and the tests that I am writing lead me to believe that most of my user-facing features can be handled by these two controllers. Sure, I can break this into more sensible compartments-like tests for a patients-controller, physicians-controller, patient-medications controller, patient-lab-results-controller and so on. But it seems to me that the only advantage here is more discreet organization.
On to the question, asides from compartmentalization, what are the reasons NOT to use as few controllers as possible, pack them with lots of actions [disadvantage], but keep the actions skinny [advantage]? Or...to take it to an extreme: Why not with MVC, have a bunch of fat models, and one skinny [albeit long] controller rather than a patient controller/model/views+tests for EACH, physician controller/model/views+tests for EACH, etc?
There's organization, as making everything inside a single controller is possible, it's going to be harder to understand and change. Instead of being able to open a file in your editor and finding the action you're looking for right away, you would be scrolling down the file to find what you're looking for.
This also leads to the God object pattern where everything happens inside a single object that's responsible for everything and everyone working at the project will be changing this same object, leading to an eternal merge hell.
And, on Rails itself, there's the RESTful-ness of the framework. Rails embraces the idea of being RESTful and one of the pillars of this idea are the resources and they can only be easily organized in separate controllers. If you try to place two different resources at the same controller you'll probably end up with crazy routes or crazy controller logic to find out which model is being represented.
If you think your controllers have a lot of repeated code, you can DRY them out using some metaprogramming magic or conventions, but it's really better to have them separated, not only for organization but also to simplify your own future maintenance.
If there's a lot of common controller logic, you might consider abstracting it out into a plugin or module that you can mix in when needed. Or the controllers could inherit from a common base controller (much as all controllers inherit by default from ApplicationController, rather than ActionController::Base).
I would advise against having one gigantic controller; a controller should manage the set of actions which pertain to a single type of resource (or the closest analog possible). This idea is even stronger if you are trying to create a RESTful design, in which each controller typically has nothing other than the basic seven actions (index, show, new, create, edit, update, destroy).
So if you want to have URLs like /patients/52394802/lab_results, I think it makes complete sense to have a LabResultsController. If these controllers are lightweight, awesome. I'm of the opinion that their existence is still justified. This shouldn't stop you from trying to make your code DRY; rather, I would simply try to abstract away the common functionality differently.
That's an impossible question to answer. Controllers are about routes and user interactions and views not business logic. Have as many controllers and actions that it makes sense to have for your links and views!
If your business logic is all in your models then it's simple enough. The main difficulty with logic in controllers is that you can't re-use the logic.
Nothing much more to say really. It's up to you to do what makes sense in your app. e.g. have a search controller to search for stuff rather than adding a search action to your existing controllers is not really about anything more than separation and clarity

Resources