Railsの小ネタ。
以下の記事にあるように default_scope
はバッドプラクティスという風潮があるみたいで、その理由も理解はできる。
要するに、default_scopeを使うと一部の処理だけdefault_scopeを外したいといった場面が必ず出てくるが、適切に解除してあげないとバグを生み出す。バグの温床なのでdefault_scope使うな。ということらしい。
そうは言ってもアプリケーションのほとんどの処理に同じscopeを適用するのも適用漏れがありそうで、それはそれでバグの温床な気がする。
そんな時にはscopingを使うと良さそう。
scoping
default_scopeがモデルの処理全てにscopeが適用されてしまうのに対して、scopingは処理のブロックの範囲にのみscopeが適用される。
これを適切に運用できれば、scopeを解除するといったバグの温床になるようなコードを書かなくても済む。
コード例
/a_service/
というprefixのパスと /b_service/
というprefixのパスのAPIエンドポイントがあり、Postモデルのデフォルトスコープをパスで切り替えたいとする。
その場合以下のように around_action
でControllerのメソッドをラップしてあげることで、デフォルトスコープを切り替えることができる。
routes.rb
namespace :a_service do
resources 'posts', only: %i(index)
end
namespace :b_service do
resources 'posts', only: %i(index)
end
ApplicationController.rb
class ApplicationController < ActionController::API
around_action :set_default_scope
def set_default_scope
scope = if request.path.start_with?('/a_service/')
Post.where(service: :a)
else
Post.where(service: :b)
end
scope.scoping do
yield
end
end
end
利用場面
1つのアプリケーションとデータベースで複数のサービスを運用したい時。(上記コード例のような)