/ / Zmätenie vyrovnávacej pamäte Otázky týkajúce sa aktívneho záznamu s Rails.cache.fetch - ruby ​​on-rails, caching

Konfigurácia vyrovnávacích pamätí Aktívne záznamové otázky pomocou programu Rails.cache.fetch - ruby ​​na koľajniciach, ukladanie do vyrovnávacej pamäte

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ď č. 1

Dô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ť.