Dwa pytania dot. zapytań ActiveRecord

Witam wszystkich,

PROBLEM 1.:

Posiadam modele: “Album”, “Category” połączone relacją “has_and_belongs_to_many”. Chciałbym uzyskać z bazy nazwy wszystkich kategorii wraz z ilością albumów, które należą do każdej z nich. Zastosowałem takie coś:

@count = Category.count(:all, :group => :category_id, :joins => :albums)

Otrzymując coś w stylu:

--- !map:ActiveSupport::OrderedHash "1": 2 "2": 1 "3": 2 "4": 1 "5": 1
Wartości się zgadzają, natomiast chciałbym zamiast id kategorii otrzymać jej nazwę (pole ‘title’). Czy da się to zrobić jednym zapytaniem czy też trzeba tworzyć nową kolekcję z połączeń dwóch zapytań: powyższego i “Category.all” ?

PROBLEM 2:

Wyciągam wszystkie albumy danej kategorii zapytaniem:

@albums = Category.find(params[:id]).albums

Chciałbym jednak dodać warunek, aby pobierał albumy tylko z flagą “published” ustawioną na “1”. Jakaś sugestia?

[quote=bauer]PROBLEM 2:

Wyciągam wszystkie albumy danej kategorii zapytaniem:

@albums = Category.find(params[:id]).albums

Chciałbym jednak dodać warunek, aby pobierał albumy tylko z flagą “published” ustawioną na “1”. Jakaś sugestia?[/quote]
To powinno pomóc:
http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html

Tam masz Osoby i Koszulki z kolorem czerwonym, tutaj masz Kategorie z albumami, które są opublikowane.

pozdrawiam

Dzięki bardzo za pomoc. Działa. Jak znajdę rozwiązanie problemu nr 1 to też dam znać.

[quote=bauer]Witam wszystkich,

PROBLEM 1.:

Posiadam modele: “Album”, “Category” połączone relacją “has_and_belongs_to_many”. Chciałbym uzyskać z bazy nazwy wszystkich kategorii wraz z ilością albumów, które należą do każdej z nich. Zastosowałem takie coś:

@count = Category.count(:all, :group => :category_id, :joins => :albums)

Otrzymując coś w stylu:

--- !map:ActiveSupport::OrderedHash "1": 2 "2": 1 "3": 2 "4": 1 "5": 1
Wartości się zgadzają, natomiast chciałbym zamiast id kategorii otrzymać jej nazwę (pole ‘title’). Czy da się to zrobić jednym zapytaniem czy też trzeba tworzyć nową kolekcję z połączeń dwóch zapytań: powyższego i “Category.all” ?[/quote]
Da się to zrobić:

Category.find(:all, :group => :category_id, :joins => :albums, :select => "*, count(category_id) as nazwa_wirtualnego_atrybutu")

Nie wiem, czy dokładnie tak będzie to działać, ale mam nadzieję, że idea jest zrozumiała. Mieliśmy problem w Postgresie, który wymaga po dodaniu GROUP BY, wymienienia wszystkich kolumn w części SELECT. Gdybyś miał tego typu problem, to listę kolumn można uzyskać w prosty sposób:

column_names = Category.column_names.join(", ") Category.find(:all, :select => "#{column_names}, count(...) as ..." ...)
Tak wyciągnięte obiekty mają wirtualny atrybut o podanej nazwie. Może nie jest to najładniejsze rozwiązanie, ale ActiveRecord raczej nie pozwala na zrobienie tego w przyjemniejszy sposób.

O tym dlaczego tak się dzieje napisałem kiedyś posta: http://rubyonrails.pl/forum/p8713-2009-03-08-16%3A13%3A14#p8713 - proponuję przeczytać :slight_smile:

problem 2

w modelu Album zrob tak:

named_scope :published, lambda {{:conditions=>["published = ?",true]}}

w kontrolerze :

@albums = Category.find(params[:id]).albums.published