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::Concern is 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:

  1. Create it in the models/concerns directory for model concerns or controllers/concerns for controller concerns.

  2. Start the module with extend ActiveSupport::Concern.

  3. Inside the concern, you can define regular methods which will become instance methods of the class including the concern.

  4. To add class methods, you can use the class_methods block.

  5. To execute code when the module is included in a class, use the included block.

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
end

In 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, Taggable makes 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