このような何か:findを使用して定数を初期化しますか?
クラスカテゴリ
SOME_CATEGORY = find_by_name("some category")
エンド
カテゴリー:: SOME_CATEGORY
は、問題なくしようとしたが、それは悪い考えであるかどうかを知りたいとの理由であれば任意..
ありがとう
このような何か:findを使用して定数を初期化しますか?
クラスカテゴリ
SOME_CATEGORY = find_by_name("some category")
エンド
カテゴリー:: SOME_CATEGORY
は、問題なくしようとしたが、それは悪い考えであるかどうかを知りたいとの理由であれば任意..
ありがとう
モデルをキャッシュするたびにデータベースにヒットしたくない場合は、これを行うにはいくつかの方法がありますが、簡単な方法の1つはMemoizationです。これはRails 2.2で導入されました。
class Category < ActiveRecord::Base
class << self
extend ActiveSupport::Memoizable
def named(name)
find_by_name(name)
end
memoize :named
end
end
このように使用します。
Category.named("some category") # hits the database
Category.named("some category") # doesn't hit the database
キャッシュは、要求を超えて永続的に維持されます。最後のパラメータとしてtrue
を渡すことでキャッシュをリセットできます。
Category.named("some category", true) # force hitting the database
何をしますか? 行う?たぶん
:
class Category
def self.some_category
Category.find_by_name("some category")
end
end
だからあなたが呼び出すことができます。
Category.some_category
=> <Category#2....>
をそれはひどいアイデアではないのですが、それはどちらか本当に良いものではありません。 Railsのやり方とはまったく同じではありません。一つのこととして、あなたは醜い定数コードの多くで終わるでしょう。 ALL_CAPS_WORDSが多すぎます。あなたのRubyはC++のように見え始めます。ブリー。
もう一つは、柔軟性がありません。これらの定数のいずれかをすべてのカテゴリに適用しますか? 2か月後に新しいカテゴリを追加する場合は、Railsコードを更新して新しい定数を追加し、再デプロイしてサーバーを再起動することを忘れないでください。あなたは非常に簡単にカテゴリにアクセスし、DBクエリを繰り返さないことができるようにすることが重要な場合
、ここではそれらを自動的に検索し、最初のアクセスでのあなたのためのLichtambergのような静的メソッドを作成しますメタプログラミングのビットです:
代わりに、この方法ではdef self.method_missing(category, *args) # The 'self' makes this a class method
@categories ||= {}
if (@categories[category] = find_by_name(category.to_s))
class_eval "def self.#{category.to_s}; @categories[#{category}]; end"
return @categories[category]
end
super
end
、いつでもあなたの最初の呼び出しCategory.ham
、それはfind_by_name("ham")
の値を返すクラスメソッドを作成します - 再びどちらのクエリもmethod_missing()
実行あなたはそれを呼び出す次回ように。これはかなり多くの方法です。OpenStructクラスが動作します。詳細を知りたい場合は、Pickaxeの本で調べてください。
(これらはすべてメモされているため、あなたのカテゴリオブジェクトに加えた変更はRailsアプリには反映されません。これは変更が行われない、または行われないことを前提にしていますそれが問題であれば@@categories
をリセットするコードにいつもafter_update
コールバックを入れることができますが、その時点でこれは複雑になり始めます)
これは、Category.some_categoryを実行するたびに新しいデータベース呼び出しを行いますが、元の質問の考え方はそうではありません。私はどちらかが悪いと言っていない、それは単なるメモです。 –