Zapiętanie danych pomiędzy kolejnymi wywołaniami akcji kontrolera

Witam,
mamy następującą sytuację:
Przyjmijmy dla uproszczenia, że w kontrolerze zaciągam sobie z bazy dość dużą ilość danych, wkładając je w odpowiednią strukturę danych, tak żeby wygodnie się je używało w widoku, gdzie wyświetlam je w formie tabeli.
Tabelę tą można sortować, i tutaj pojawia się mój problem: przy każdym sortowaniu wywołuję odpowiednią metodę z kontrolera i muszę zaciągać oraz obrabiać te dane, mimo że nie zmieniły się one od ostatniego requesta i wystarczyłoby przesortować strukturę danych, gdyby ona nadal istniała.
Czy mogę sobie w jakiś sposób zapisać w pamięci moją strukturę danych, tak żeby przy sortowaniu korzystać z niej a nie tworzyć od nowa? Czy to jest możliwe tylko przy wykorzystaniu sesji (zapisanie w sesji) ?

sesja albo cache

Zasadniczo Lotus Ci napisał (sesja, przy czym z taką ilością danych to zdecydowanie nie w ciachu, tylko po stronie serwera – file store albo ActiveRecord store) co trzeba zrobić, natomiast – you’re doing it wrong :smiley:

Po to właśnie jest paginacja (stronicowanie) oraz klauzule LIMIT w SQLu, żeby dane wyciągać w małych porcjach i zrzucić na bazę danych ciężar ich sortowania czy ogólnie podawania w wymaganej ilości i kolejności.

Zgadzam się z Tomashem, że powinieneś zrefaktoryzować kod, a nie cache’ować tego obiekty, ale jeżeli już musisz, to ja bym nie trzymał tego w sesji…

  1. Nie powinno się trzymać obiektów w sesji
  2. Wydajność - przy dużej ilości danych na każdej stronie będzie trzeba te dane załadować

Najlepiej skorzystać z memcached.

[code]#instalujemy memcached
memcached -d

w environment.rb

ActionController::Base.cache_store = :mem_cache_store, “127.0.0.1”

w controllerach:

Rails.cache.write([“some_key”, session[:session_id]], @object_to_cache)
Rails.cache.read([“some_key”, session[:session_id]])[/code]
Taka konstrukcja zapewni to, że dane będą powiązane z sesją (session_id w kluczu), ale nie będą w sesji siedziały, więc nie trzeba będzie ich pobierać przy każdym requeście.

Oczywiście masz rację ale (jak dla mnie), to jest to niemożliwe ponieważ te dane znajdują się w kilku tabelach i wymagają przetworzenia (zliczenia, przeliczenia, pogrupowania, sortowania…) - jest to forma raportu.

Dzięki za pomoc, pobawie się w najbliższym czasie.

skoro dane sa takie same to nie mozna ich przetworzyc po stronie uzytkownika np. za pomoca tego pluginu :
table sorter
i kilku dodatkowych metod??

Świetny plugin! Na pewno go wykorzystam! :wink:

Teraz inna sprawa…
Powiedzmy, że chce wyeksportować pobrane dane do jakiegoś innego formatu, np. pdf, xls, doc, …
Eksport następuje po kliknięciu w linka. Chcąc uniknąć niepotrzebnego zaciągania z bazy danych zrobiłem coś takiego:

[code] # Pobieranie, przetwarzanie danych
# …

File.open("test.xls", "w") do |file|
  file.syswrite(render_to_string :file => "raport.xls", :layout => false)
end

render "raport"[/code]

Idea jest taka, żeby zrobić eksport od razu po zaciągnięciu danych z bazy i nie powtarzać całego procesu po kliknięciu w linka.
Nasuwa mi się tylko pytanie: czy "render_to_string :file => … " na pewno robi to, co chcę, tzn. czy do renderingu używa danych, które przed chwilą pobrał, a nie odpala akcji od nowa?

Użyj send_file