Help us understand the problem. What is going on with this article?

rails concernの使い方

More than 1 year has passed since last update.

初めに

rails の concernについてちょっとまとめたもの

concernとは

concernとはrailsの共通部分をまとめるみたいな使い方が一般的なようで、例えばuserモデルでもpostモデルでも使うスコープなりメソッドがあった場合にまとめることができます。

以下は今日と機能に作成されたデータを得るスコープです。

user.rb
scope :today, -> {where(created_at: 0.day.ago.all_day)}
scope :yesterday, -> {where(created_at: 1.day.ago.all_day)}


post.rb
scope :today, -> {where(created_at: 0.day.ago.all_day)}
scope :yesterday, -> {where(created_at: 1.day.ago.all_day)}

みたいな感じで書いているとしてこれはおんなじスコープを書いているのでまとめたい!というときにconcernを使います。

concernsフォルダがmodels以下にあると思うのでその中にday.rbというファイルを作成します。

そしてその中に

day.rb
module Day
  extend ActiveSupport::Concern

  included do
    scope :today, -> {where(created_at: 0.day.ago.all_day)}
    scope :yesterday, -> {where(created_at: 1.day.ago.all_day)}
  end 
end 

moduleの名前はファイルの名前と同じにする必要があります。

そしてuser.rb,post.rbに

user.rb
include Day
post.rb
include Day

と書いたら使えるようになります。

ほかの使い方

自分でアプリを作っていて複数のモデルでおんなじスコープを使いたいとかあんまりないのですがモデルのファイルやapplication_controller.rbの中身が多くなりすぎて見づらくなるということが結構ありました。

なので見やすくするためにある程度処理をまとめてconcernの中に入れています。

例えばapplication_controller.rbのエラーハンドルを書いていた場合

        class Forbidden < ActionController::ActionControllerError; end 
        class IpAddressRejected < ActionController::ActionControllerError; end 

        rescue_from Exception, with: :rescue500
        rescue_from ActiveRecord::RecordNotFound, with: :not_found
        rescue_from Forbidden, with: :rescue403
        rescue_from IpAddressRejected, with: :rescue403
        rescue_from ActionController::RoutingError, with: :rescue404

        def rescue500(e)
            @exception = e 
            render 'error_messages/500'
        end 

        def rescue403(e)
            @exception = e 
            render 'error_messages/403' 
        end 


        def not_found(e)
            @exception = e
            render 'error_messages/404'
        end 

        def rescue404(e)
            @exception = e 
            render 'error_messages/404'
        end 

みたいなのがapplication_controller.rbに書かれています。

正直これだとapplication_controllerが見づらいです。

なので

controllers/concernsに

error_handle.rbというファイルを作り

その中に


module ErrorHandle

    extend ActiveSupport::Concern

    included do 
        class Forbidden < ActionController::ActionControllerError; end 
        class IpAddressRejected < ActionController::ActionControllerError; end 

        rescue_from Exception, with: :rescue500
        rescue_from ActiveRecord::RecordNotFound, with: :not_found
        rescue_from Forbidden, with: :rescue403
        rescue_from IpAddressRejected, with: :rescue403
        rescue_from ActionController::RoutingError, with: :rescue404

        def rescue500(e)
            @exception = e 
            render 'error_messages/500'
        end 

        def rescue403(e)
            @exception = e 
            render 'error_messages/403' 
        end 


        def not_found(e)
            @exception = e
            render 'error_messages/404'
        end 

        def rescue404(e)
            @exception = e 
            render 'error_messages/404'
        end 
    end 
end 

とかいてapplication_controller.rbでincludeしてあげれば中身は

class ApplicationController < ActionController::Base
    include ErrorHandle
end

みたいにすっきりします。

自分の場合は配列とその中身をfreezeさせるメソッドfreeze_allを作ってそれを使うことがあるのですがそういうのは

concernsにsome_methods.rbというファイルをつくって

some_methods.rb
module SomeMethods
    extend ActiveSupport::Concern

    def freeze_all
        self.each do |item|
            item.freeze 
        end 
        self.freeze
    end
end 

みたいに使うメソッドもまとめてます。

こういったやり方がありなのか知らないけど…

おわり:sunny:

sibakenY
大学卒業後Ruby, Ruby on Railsを勉強しています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした