Controller Concerns
With so many options, it might be good to think about reusability across controllers. Your current setup is flexible and if you anticipate using similar logic in other controllers, then having it in a concern makes it easily reusable. - ChatGPT (regarding :index's QueryParamsProcessor)
Concerns in Rails are a way to make large models or controllers more organized by extracting reusable pieces of functionality into mixable modules. This technique is particularly beneficial when you have methods or functionalities that are shared across multiple models or controllers.
Here's a more detailed breakdown:
1. Purpose:
DRY (Don't Repeat Yourself): If there's code shared across multiple models or controllers, concerns help centralize that code.
Organization: Concerns allow you to split large models or controllers into smaller, more focused pieces, making them easier to understand and maintain.
2. ActiveSupport::Concern:
ActiveSupport::Concernis a module provided by Rails that gives some additional functionalities over standard Ruby modules. It offers a more natural way to declare class-level methods and includes shared code.
3. Usage:
To use a concern:
Create it in the
models/concernsdirectory for model concerns orcontrollers/concernsfor controller concerns.Start the module with
extend ActiveSupport::Concern.Inside the concern, you can define regular methods which will become instance methods of the class including the concern.
To add class methods, you can use the
class_methodsblock.To execute code when the module is included in a class, use the
includedblock.
4. Example:
Let's say you have methods related to "taggable" functionality that you want to share across different models.
# app/models/concerns/taggable.rb
module Taggable
extend ActiveSupport::Concern
included do
has_many :tags
end
def list_tags
tags.pluck(:name).join(", ")
end
class_methods do
def top_tags(limit = 10)
# some class method logic here
end
end
end
# In your model:
class Article < ApplicationRecord
include Taggable
end
class Product < ApplicationRecord
include Taggable
endIn the above example, both Article and Product will have the list_tags instance method and the top_tags class method. Additionally, when the module is included, the has_many :tags association is set up due to the included block.
5. Things to Keep in Mind:
Granularity: It can be tempting to move lots of code into concerns. However, avoid making them too granular. If something is used only in one model, it may not make sense to put it in a concern.
Overuse: Avoid using concerns just for the sake of using them. It should make logical sense to extract functionality into a concern.
Naming: Name the concern in a way that clearly indicates its responsibility. For example,
Taggablemakes it evident that it's about tagging functionality.
In summary, concerns in Rails provide a structured way to share functionality across models or controllers and help in keeping the codebase DRY and organized.
Last updated