Sumowanie komentarzy każdego posta

Witam, proszę o pomoc z kolejnym problemem. Otóż chciałbym żeby na moim forum pod każdym postem wyświetlała się liczba dodanych do niego komentarzy. Nie wiem jak odpowiednio zdefiniować zmienną która posłużyłaby mi w widoku index. Akcja komentowania działa bez zarzutu, odpowiednie komentarze wyświetlają się pod odpowiednim postem, ale co zrobić by je zliczyć? Wiem że w akcji show wystarczyłoby zrobić @post.comment.count, ale jak to zrobić w index skoro tam nie da się zainicjować @post = Post.find(params[:id])? Czy za pomocą instrukcji warunkowej która będzie porównywać post.id z comment.post_id? Pomóżcie proszę.

MODEL POST

class Post < ActiveRecord::Base
has_many :comment
end

MODEL COMMENT

class Comment < ActiveRecord::Base
belongs_to :post
end

MIGRACJA POSTÓW

class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.column :title, :string
t.column :text, :text
t.column :author, :string
t.column :author_id, :integer
t.column :data, :datetime
end
end

def self.down
drop_table :posts
end
end

MIGRACJA KOMENTARZY

class CreateComments < ActiveRecord::Migration
def self.up
create_table :comments do |t|
t.column :text, :text
t.column :author, :string
t.column :author_id, :integer
t.column :post_id, :integer, :foreign_key => :posts
t.timestamps
end
end

def self.down
drop_table :comments
end
end

KONTROLER POSTÓW

class PostsController < ApplicationController
include ApplicationHelper
helper :profile
before_filter :protect, :only => [:index, :edit]

def index
@posts = Post.all
respond_to do |format|
format.html
format.xml { render :xml => @posts }
end
end

def show
@post = Post.find(params[:id])
@user = User.find(session[:user_id])
respond_to do |format|
format.html
format.xml { render :xml => @post }
end
end

def new
@post = Post.new
respond_to do |format|
format.html
format.xml { render :xml => @post }
end
end

def edit
@post = Post.find(params[:id])
end

def create
@post = Post.new(params[:post])
@post.data = Time.now
@user = User.find(session[:user_id])
@post.author = @user.screen_name
@post.author_id = @user.id
if @post.save
flash[:notice] = ‘Post został dodany’
redirect_to :action => ‘index’
else
render :action => ‘new’
end
end

def update
@post = Post.find(params[:id])
respond_to do |format|
if @post.update_attributes(params[:post])
format.html { redirect_to(@post, :notice => ‘Post został zaktualizowany’) }
format.xml { head :ok }
else
format.html { render :action => “edit” }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
end
end
end

def destroy
@post = Post.find(params[:id])
@post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end

def comment
@post = Post.find(params[:id])
@user = User.find(session[:user_id])
@text = (params[:comment].values_at “text”).to_s
@post.comment.create(:text => @text, :author => @user.screen_name, :author_id => @user.id)
flash[:notice] = “Komentarz został dodany”
redirect_to :action => ‘show’, :id => @post
end
end

Z góry dziękuję za wszelką pomoc, pozdrawiam!

Skoro wkontrolerze w index masz

@posts = Post.all

to możesz w widoku zrobić:

<% @posts.each do |post| %> <%= post.title %> - <%= post.comments.count %> <% end %>

RailsGuides#Calculations

I pomyśl też nad counter_cache, żeby nie zaorać bazy - http://railscasts.com/episodes/23-counter-cache-column :wink:

super, dziękuję Panowie i już siadam nad studiowaniem tego co polecił zlw. Mam tylko jeszcze jedno pytanie:

po użyciu w partialu kodu podanego przez warszk (poprawionego o literówkę związaną z “comment” zamiast “comments”):

<% @posts.each do |post| %>
<%= post.title %> - <%= post.comment.count %>
<% end %>

wszystko pięknie działa, z tym że przy każdym poście wyświetlają się wszystkie liczby odpowiadające za ilość komentarzy we wszystkich istniejących postach.
To znaczy że jeśli np. w pierwszym poście mam 3 komentarze, w drugim 2 a w trzecim 4, to przy każdym poście (pomijając zbędny tytuł) wyświetlają się liczby 2,3 oraz 4. Jak napisać instrukcję (i przede wszystkim gdzie, w kontrolerze czy raczej w widoku), która odpowiednio porówna jaka liczba winna widnieć przy danym poście? Wiem (to znaczy podejrzewam) że należałoby to zrobić porównaniem post.id = comment.post_id ale coś mi nie wychodzi. Może ktoś jeszcze wesprzeć :)? Z góry bardzo dziękuję.

Pokaż jakiś większy fragment kodu, bo to mało możliwe co opisałeś.

Pomijając zbędną otoczkę wygląda to mniej więcej tak:

index

<%= render :partial => “post”, :collection=> @posts.reverse %>
<%= link_to ‘Nowy post’, :action => ‘new’ %>

partial

  Wrzucone <%=h post.data.to_s(:short) %> przez: <%=h post.author%>
 <%=h post.title %>
 <% @posts.each do |post| %>
 Komentarzy: <%= post.comment.count %> 
 <% end %>
<%= link_to 'Pokaż', :action => 'show', :id => post %>
<%= link_to 'Edytuj', :action => 'edit', :id => post %>
<%= link_to 'Usuń', post, :confirm => 'Jesteś pewny?', :method => :delete %>

Jako, że jest to w partialu to w sumie nie jest to mało możliwe ;P, i przy każdym poście rzeczywiście widnieje “Komentarzy: 3 2 4” .

[quote=switchu]<% @posts.each do |post| %>
Komentarzy: <%= post.comment.count %>
<% end %>[/quote]
Po co?

Daj po prostu:

Komentarzy: <%= post.comment.count %>

Sebcioz , rządzisz. Dzięki bardzo, teraz wszystko hula tak jak hulać powinno :slight_smile: Wychodzi na to że zanim zaczerpnąłem pomocy na forum byłem blisko rozwiązania problemu samemu, ale pobłądziłem :stuck_out_tongue: Dzięki Wam wszystkim że pomogliście mi wrócić na właściwy tor, pozdrawiam!