Quick Dive into Rails Concerns

In Ruby on Rails, concerns are modules that encapsulate common behaviors that can be shared among different model classes, controllers, or other components of the application. Concerns are used to avoid code repetition and maintain code modularity and organization.

They are especially useful when you have functionalities that are shared among different models or controllers but are not part of the core logic of those classes. For example, if you have methods or validations that are applicable to multiple models, you can extract these behaviors into a Concern and include them in the relevant classes.

Let’s say you have authentication-related methods that you want to share among different models. In this case, you can choose to include these methods directly in each model where they are needed.

1
2
3
4
5
6
7
# app/models/user.rb
class User < ApplicationRecord
  # Example authentication method
  def authenticate(password)
    # Authentication logic here
  end
end
1
2
3
4
5
6
7
# app/models/admin.rb
class Admin < ApplicationRecord
  # Example authentication method
  def authenticate(password)
    # Authentication logic here
  end
end

In this example, the authentication methods authenticate are defined directly within each model (User and Admin). While this works, it can lead to code duplication if you have many models that need the same authentication methods.

With the use of Concerns, you can centralize the authentication logic in a single place and include it in relevant models in a cleaner and more organized way.

To create a Concern in Ruby on Rails, you typically create a file within the app/models/concerns or app/controllers/concerns directory, depending on where you want to share the code. Inside this file, you define a module that contains the methods and functionalities you want to share.

For example, suppose you have a set of authentication-related methods that you want to share among different models. You could create a concern called Authenticatable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# app/models/concerns/authenticatable.rb
module Authenticatable
  extend ActiveSupport::Concern

  included do
    # Add shared instance methods here
    # Example:
    # has_secure_password
  end

  class_methods do
    # Add shared class methods here
    # Example:
    # def authenticate(email, password)
    #   user = find_by(email: email)
    #   user && user.authenticate(password)
    # end
  end
end

Then, you can include this Concern in the relevant models:

1
2
3
4
# app/models/user.rb
class User < ApplicationRecord
  include Authenticatable
end
1
2
3
4
# app/models/user.rb
class Admin < ApplicationRecord
  include Authenticatable
end

This way, all the methods defined in the Authenticatable concern will be available to the User and Admin classes.

Concerns are a powerful tool in Ruby on Rails for modularizing and reusing code efficiently, helping to keep your application organized and DRY (Don’t Repeat Yourself).”