Moja verzia je:
- Koľajnice: 3.2.6
- dalli: 2.1.0
Moje env je:
- config.action_controller.perform_caching = true
- config.cache_store =: dalli_store, "localhost: 11211", {: namespace => "MyNameSpace"}
Keď píšem:
Rails.cache.fetch(key) do
User.where("status = 1").limit(1000)
end
Model používateľa nie je možné uložiť do vyrovnávacej pamäte. Ak používam
Rails.cache.fetch(key) do
User.all
end
dá sa uložiť do vyrovnávacej pamäte. Ako uložiť výsledok dotazu do vyrovnávacej pamäte?
odpovede:
31 pre odpoveď č. 1Dôvodom je to, že
User.where("status = 1").limit(1000)
vráti ActiveRecord::Relation
čo je vlastne rozsah, nie dotaz. Koľajnice ukladajú do rozsahu pôsobnosti cache.
Ak chcete dotaz uložiť do vyrovnávacej pamäte, musíte na konci použiť metódu dotazu, napríklad #all
.
Rails.cache.fetch(key) do
User.where("status = 1").limit(1000).all
end
Vezmite prosím na vedomie, že nikdy nie je dobrý nápad ukladať objekty ActiveRecord do vyrovnávacej pamäte. Ukladanie do pamäte cache objektu môže mať za následok nekonzistentné stavy a hodnoty. Primitívne objekty by ste mali vždy ukladať do medzipamäte, ak je to možné. V takom prípade zvážte uloženie ID do medzipamäte.
ids = Rails.cache.fetch(key) do
User.where("status = 1").limit(1000).pluck(:id)
end
User.find(ids)
Môžete namietať, že v tomto prípade je volanie na číslo User.find
vždy sa vykoná.Je to pravda, ale dopyt pomocou primárneho kľúča je rýchly a obídete problém, ktorý som už popísal. Ukladanie do pamäti objektov aktívneho záznamu môže byť navyše drahé a môžete rýchlo skončiť vyplnením celej pamäte Memcached iba jedným jediným záznamom v pamäti cache. identifikátory tiež zabránia tomuto problému.
3 pre odpoveď č. 2
Okrem vybranej odpovede: pre Rails 4+ by ste mali použiť load
namiesto all
za získanie výsledku rozsahu.
2 pre odpoveď č. 3
Rails.cache.fetch
uloží presne to, čo blok vyhodnotí.
User.where("status = 1").limit(1000)
Je len rozsah, takže do vyrovnávacej pamäte sa dostane iba objekt ActiveRecord :: Relation, tj dotaz, ale nie jeho výsledky (pretože dotaz ešte nebol vykonaný).
Ak chcete uložiť niečo užitočné do medzipamäte, musíte vynútiť vykonanie dotazu vo vnútri bloku, napríklad vykonaním príkazu
User.where("status = 1").limit(1000).all
Všimnite si, že na koľajniciach 4, all
silové zaťaženie vzťahu - použitie to_a
namiesto
0 pre odpoveď č. 4
Použitím
User.where("status = 1").limit(1000).all
by mal fungovať.