冒險村27 - Concern

27 - Concern

最後整理的方式再來講到 Rails 提供功能,主要目的在把相同邏輯 code 整理在一起,需要使用的時候再 include 近來即可使用,有點類似繼承的概念,但又不想要所有東西都繼承起來。或許會發生有一兩個特別的不需要使用到,這時候就可以使用 Concern 來處理。

用途主要在:

  1. 用於將程式寫在同一個 concern,提高可讀性也方便重構。
  2. 把 model or controller 重複的功能寫在同一個 concern。

Create concerns folder in controller or model folder

  • users_concern.rb

Add app > controllers > concerns > users_concern.rb

module / concern 兩種寫法的定義都相同,看習慣寫成什麼樣子都可以,我個人常看到的是 module + included。

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
# definition(1)
module UserConcern
extend ActiveSupport::Concern

def self.included(base)
base.instance_eval do
scope :some_thing_scope, -> {...}
has_many :table
end
# or
# base.class_eval do
# ...
# end
end

#or
included do
#...
end
end

# definition(2)
concern UserConcern do
...
end

看完上述的寫法,以 user controller 整理舉例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# frozen_string_literal: true
module UserConcern
extend ActiveSupport::Concern
# render_404_if_user_id_invalid in here
include ValidateParams

included do
before_action -> { render_404_if_user_id_invalid(params[:id]) }
before_action :set_basic_user_instances
end

def set_basic_user_instances
@some_instances = ...
# ...
end
end
1
2
3
4
class UserController < ApplicationController
include UserConcern
# ...
end

而相同的,model 也可以用相同的方法整理再一起,這邊也不另外舉例了。