Rails ActiveSupport Concerns
mouse 1796 · person cloud · link
Last update
2017-04-11
2017
04-11
« — »

Put this template in your /app/(models|controllers)/concerns folder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# /app/(models|controllers)/concerns/my_module.rb
module MyModule
  extend ActiveSupport::Concern

  included do
    scope :disabled, -> { where(disabled: true) }
    before_save :my_instance method
    ...
  end

  # use this syntax with Rails 5
  class_methods do
    def my_class_method
      ...
    end
  end # class_methods

  # use this syntax with Rails 4
  module ClassMethods
    def my_class_method
      ...
    end
  end # module ClassMethods

  def my_instance_method
    ...
  end
end

Then load it in your model/controller:

1
2
3
4
5
6
7
class MyModel < ActiveRecord::Base
  include MyModule
end

class MyController < ApplicationController
  include MyModule
end

NOTE: for Rails < 4 remember to configure autoload_paths in /config/application.rb like this:

1
2
3
4
5
6
7
8
module MyAppName 
  class Application < Rails::Application
    # Custom directories with classes and modules you want to be autoloadable.
    # config.autoload_paths += %W(#{config.root}/extras)
    config.autoload_paths << Rails.root.join('app', 'models'     , "concerns")
    config.autoload_paths << Rails.root.join('app', 'controllers', "concerns")
  end
end

WARNING: Moldel and controller concerns have the same scope! If you define two files with the same name but different path (eg: /app/models/my_module.rb and /app/controllers/my_module.rb) they will clash and only the last one loaded will be used.


Sources: DHH, Rails Api, StackOverflow