Dziwnie się zachowuje zmienna @comments, będę wdzięczny o podpowiedź.
W kontrolerze mam:
def show
@entry = Entry.find(params[:id])
@comments = @entry.comments
end
W widoku próbuję wyświetlić komentarze i pokazuje mi, że @comments.empty? jest true, ale wystarczy, że przed tym kodem dodam <%= @comments %>
żeby nagle zmienna @comments była tablicą z komentarzami, a .empty? zwracał ładnie false, tak jakby zapytanie o komentarze zostało wykonane dopiero właśnie przy dodaniu tej linii.
<% if !@comments.empty? %>
<% @comments.each do |comment| %>
<%= comment.id %>
<% end %>
<% end %>
I pytanie, jak powinienem to zrobić, żeby @comments było wypełnione już przy IF-ie, bez żadnego kombinowania?
To nie jest możliwe. Coś musi być źle, albo wydaje Ci się że masz tak jak opisałeś a w rzeczywistości jest inaczej.
Jeśli wszystko jest tak jak opisałeś, a Entry#comments to asocjacja ActiveRecord, nie powinno być tego problemu. Sorry że nie mogę być bardziej pomocny, może podziel się kodem z modeli?
To jednak “tylko” nieco niespójny charakter counter_cache.
Masz w modelu Entry pole comments_count. ActiveRecord przewiduje, że kolumna o takiej nazwie (nazwa relacji + _count)
jest używana do przechowywania aktualnej liczby rekordów w danej relacji.
Aby ta kolumna automatycznie uaktualniała się przy tworzeniu/usuwaniu, trzeba dodać counter_cache: true
w konfiguracji belongs_to.
Niespójność polega na tym, że nawet bez podania tego parametru (oraz po podaniu counter_cache: false :)) ) , kolumna ta jest brana pod uwagę (https://github.com/rails/rails/blob/master/activerecord/lib/active_record/associations/has_many_association.rb#L74) przez metodę size (i wszystkie pochodne, czyli m.in. empty?).
Tak to będzie działać:
class Comment < ActiveRecord::Base
attr_accessible :child, :content, :entry_id, :level, :parent_id, :rank, :user_id
belongs_to :entry, :counter_cache => true
belongs_to :user
belongs_to :parent, class_name: "Comment", foreign_key: "parent_id"
has_many :children, class_name: "Comment", foreign_key: "id"
end
Btw. dla ustawiania poprawnej wartości takich rozsynchronizowanych liczników jest metoda reset_counters (http://api.rubyonrails.org/classes/ActiveRecord/CounterCache.html#method-i-reset_counters)