質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

628閲覧

クラスインスタンス変数を使ってDBアクセスを減らす方法

thesnowman

総合スコア154

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2022/01/25 22:39

編集2022/01/25 22:45

Policy(規約)というモデルがあり、versionというカラムを持っています。
最新の規約バージョンを取得したいとき、一般的にはscopeを使うと思います。

ですが、scopeだと毎回DBにアクセスしてしまうので頻繁に使う場合好ましくありません。
そこでクラスメソッドを定義して、クラスインスタンス変数に代入する形にすればよいのではと思いました。

ですが、ネットで検索してもクラスインスタンス変数をつかったこのような手段は見つからず、何かしらの理由があって使われていないのかなと思ったのですが、理由がわかりません。
非常に良い手段だと思ったのですがいかがでしょう?

ruby

1class Policy < ApplicationRecord 2 3 # 一般的な手段、毎回DBアクセスしてしまう 4 scope :latest_version -> { maximum(:version) } 5 6 # これならDBアクセスを減らせる? 7 def self.latest_version 8 @latest_version ||= maximum(:version) 9 end 10 11end
Policy.latest_version #=> 10

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

何かしらの理由があって使われていないのかなと思ったのですが、理由がわかりません。

本番サーバでは、クラスはサーバ起動時に作られてそれっきりなので、データベースを更新してもlatest_versionが更新されません。

もちろん、「Policyの更新を画面内から行うことはなく、サーバ再作成を伴うデプロイ処理でしか更新されない」というのであればこの構造もありです。

投稿2022/01/26 00:14

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thesnowman

2022/01/26 00:42

ありがとうございます!! なるほど、そんな理由が、、 Rails.cacheもありがとうございます。 重ね重ねになって恐縮なんですが、リクエストごとにDBにアクセスしなおして、ひとつのリクエストに対する処理内ではDBから一度取得したのが共有されるようにしたい場合のやり方ってありますでしょうか?
thesnowman

2022/01/26 01:28

maisumakunに送ってもらったページに以下のようにありました。リクエスト単位でのキャッシュはデフォルトで行われているかもしれません。確かめてみます。 >1.8 SQLキャッシュ >Railsのクエリキャッシュは、各クエリによって返った結果セットをキャッシュする機能です。リクエストによって >以前と同じクエリが発生すると、データベースへのクエリを実行する代わりに、キャッシュされた結果セットを利用>します。 >データベースに対して同じクエリが再度実行されると、実際にはデータベースにアクセスしません。1回目のクエリ > では、結果をメモリ上のクエリキャッシュに保存し、2回目のクエリではメモリから結果を読み出します。 https://railsguides.jp/caching_with_rails.html#sql%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5
thesnowman

2022/01/26 05:53 編集

結論、キャッシュからいけてました!! 簡略化してますが、 例えばUser.allを4回実行すると以下のようになりました。ありがとうございました! ``` User Load (2.7ms) SELECT * FROM "users" CACHE User Load (0.1ms) SELECT * FROM "users" CACHE User Load (0.1ms) SELECT * FROM "users" CACHE User Load (0.1ms) SELECT * FROM "users" ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問