Railsのクラス変数のキャッシュ保持の仕様について
概要
現在Rails6系で作成中のアプリにおいて、仕様がかなり被っている二つのモデルを扱っています。
CRUDアクションを各コントローラーに別々に書くのはDRYでは無いので、コントローラー、モデルの双方ついて抽象クラスを作ってそちらにCRUDアクションを定義しています。
当然、抽象クラス内からどちらのモデルにクエリを出すのかを判別する必要があるので、クラス変数として該当のモデルをセットして呼び出す仕様にしているのですが、リクエスト毎にクラス変数が更新され無い状況です。
具体的には、後述のコード中において、
self.modelの中身が毎回変わってくれず、Dog::CategoriesControllerにアクセスしているのにcat_categoriesテーブルにクエリが行ってしまうという状況です。
おそらくクラスの初期化が毎回行われずにキャッシュされたものをRailsが使っているという事なのかと思いますが、
恥ずかしながらこのあたりの仕様について理解しておらず、対応策について困っています。
※一応ですがRailsはAPIモードで開発しており、viewについては別で開発しております。
質問
リクエスト毎にクラス変数がセットされる様にするためにはどうすれば良いか?
もしくは、その方法があったとしてもその方法を取る事はパフォーマンス等の観点から問題があれば、どの様に対応するのがベストか?
(後者については抽象的な質問になってしまっており恐縮ですが、、、)
コード
Controller
- ApplicationController
Ruby
1class ApplicationController < ActionController::API 2 def initialize 3 super 4 self.model = self.class.get_model_class 5 end 6 7 def self.call_default_functions 8 self.set_class_name_prefix 9 self.set_class_name_suffix 10 end 11 12 def self.set_class_name_prefix 13 @@class_name_prefix = self.name.split('::')[0] 14 end 15 16 def self.set_class_name_suffix 17 @@class_name_suffix = self.name.gsub(/Controller/, '').split('::')[-1] 18 end 19 20 def self.get_model_class 21 "#{self.class_name_prefix}::#{self.class_name_suffix.singularize}".safe_constantize 22 end 23end
- 抽象Controller
Ruby
1class Abstract::CategoriesController < ApplicationController 2 def index 3 categories = self.model.find_index({query: category_params}) 4 render json: {result: true, body: self.model.to_json(cards)} 5 end 6end
- 具体Controller
Ruby
1class Dog::CategoriesController < Abstract::CategoriesController 2 self.call_default_functions 3 4 private 5 def category_params 6 params.require(:category).permit( 7 :name, 8 ) 9 end 10 end 11end
※似た様な形でCat::CategoriesControllerがあると考えていただけると幸いです。
Model
- 抽象Model
class Abstract::Category < ApplicationRecord self.abstract_class = true def self.define_common_associations #class_name_prefixなどはコントローラーと同様にapplication_recordで定義しています。 has_many :foods, class_name: "#{self.class_name_prefix}::Food", foreign_key: "#{self.table_name_prefix}_food_id" end end
- 具体モデル
Ruby
1class Dog::Category < Abstract::Category 2 self.define_common_associations 3 self.find_index(params) 4 return self.all 5 end 6end
お手数ですが、何卒よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー