Podział na Kategorie

Przeczytałem kilka wątków na ten temat, ale mimo to nie mogłem znaleźć rozwiązania.

Postanowiłem aby w blogu na stronie głównej przechowywać podział postów ze względu na kategorie. Użyłem Join Table z post_id oraz category_id
Do tego celu użyłem następującego fragmentu kodu:

[code]<% for category in @categories %>

<%=h category.title %>

<%=h category.description %>

    <% for post in category.posts %>
  • <%= post.title %>
  • <% end %>

<% end %>[/code]
Pojawia mi się komunikat:
Couldn’t find Post with ID=list

oraz fragment dziennika błędów:
E:/InstantRails-2.0-win/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1267:in find_one' E:/InstantRails-2.0-win/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1250:infind_from_ids’
E:/InstantRails-2.0-win/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:504:in find' app/controllers/admin/posts_controller.rb:26:inshow’

Wiem tylko, że jest to związane z faktem, że domyślnie akcja list nie istnieje i jest zastępowana akcją show.

Jak można inaczej zaimplementować podział postów ze wzdlędu na kategorie?

Jak mam wyświetlić kategorię do której należy dany post np. przy akcji show? Przy użyciu Join Table

Kod widoku jest w porządku. Dawaj modele.

model post

class Post < ActiveRecord::Base validates_presence_of :title, :body has_many :comments has_and_belongs_to_many :categories end
model category

class Category < ActiveRecord::Base validates_presence_of :title has_and_belongs_to_many :posts end

Raczej kontroller :wink:

E:/InstantRails-2.0-win/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:504:in `find' app/controllers/admin/posts_controller.rb:26:in `show'

Czy na pewno w tabeli categories_posts masz tylko dwa pola: post_id i category_id. Czy na przykład nie masz jeszcze trzeciego - id? Dla ułatwienia dodam, że jesli nie użyłeś w migracji :id => false, to masz :wink:

A jeśli masz, to tutaj pewnie tkwi błąd, bo przy has_and_belongs_to_many mieć nie wolno.


akcja show:

[code] def show
@post = Post.find(params[:id])

respond_to do |format|
  format.html # show.html.erb
  format.xml  { render :xml => @post }
end[/code]

jedna, rzecz. Chodzi o to, że show używa się do pokazywania konkretnego posta. Zaś do listowania postów używam akcji list standardowo niedostępnej.

def list @categories = Category.find(:all, :order => 'title') end
żeby działało trzeba zmodyfikowąć plik: routes.rb z:

map.resources :posts

na:

resources :posts, :collection => {:list => 'get'}

może sami sprawdźcie tego linka. Tu jest podcast z JoinTable i wszystko wyjaśnione, jednak w pewnym miejscu nic mi nie działa. Oto link: http://www.buildingwebapps.com/LearningRails/17

Daj tą linijkę

    @categories = Category.find(:all, :order => 'title')

zamiast tej:

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

ale nie rozumiałbym wtedy idei akcji show. Bo widzę, że w akcji show nie masz wyświetlanej jednej! kategorii, czy też jednego! postu. Zatem celem Twojej akcji show jest lista wszystkich kategorii i postów z nią powiązanych. Jeśli chcesz wyświetlić pojedynczy post i kategorie z nim powiązane do w akcji show kontrolera post:

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

a w widoku

[code]<%= @post.title %>
<% for category in @post.categories %>

<%=h category.title %>

<%=h category.description %>

<% end %>[/code] jeśli kategorie, to odwrotnie.

pozdrawiam

ps. pamietaj o tym id o którym wspomniał sharnik, ale patrząc na podany artykuł jest :id => false

@sharnik, id jest false, o to zadbałem

@punkracy dzięki, o to właśnie mi chodziło. Działa poprawnie.

Czyli jakbym chciał sortować po kategoriach muszę zastosować coś takiego:

[code]w kontrolerze:
@category = Category.find(params[:id])
w widoku:
<%= @category.title %>
<% for post in @category.posts %>

<%=h post.title %>

<%=h post.body %>

<% end %>[/code] załóżmy, że w menu (czyli layout) chcę mieć wylistowane kategorie jako url a w nich posegregowane posty to trzeba zrobić po prostu analogicznie. Teraz już rozumiem zasadę działania. Dzięki raz jeszcze za pomoc. :cool: