Railsy uzyskują liczbę asocjacji za pośrednictwem tabeli złączeń
To pytanie jest rozwidleniem z
Asocjacje HABTM w Railsach: zbieranie i liczenie kategorii modelu potomnego
https://coderoad.ru/30130380/
.
Dany:
>
class Category < ActiveRecord::Base
has_and_belongs_to_many :books
validates_uniqueness_of :name
endclass Book < ActiveRecord::Base
has_and_belongs_to_many :categories
endclass Store < ActiveRecord::Base
has_many :books
has_many :categories, through: :books
end
Zadanie:
>
Podając sklep, podaj liczbę książek w każdej kategorii.
Store.first.books_per_category
pożądany rezultat:
[ { name: 'mystery', count: 5 }, { name: 'fantasy', count: 6 } ]
Jednak każdy sklep może mieć ogromną liczbę książek i kategorii.
.
Próbuję utworzyć jedno zapytanie dotyczące wydajności, które pobiera tylko kolumnę z nazwą i liczbę książek dla każdej odrębnej kategorii związanej ze sklepem, bez ładowania książek do pamięci.
Próbowałem do tej pory:
>
class Store < ActiveRecord::Base # Will load each book into memory
def books_per_category
categories.eager_load(:books).map do |c|
{
name: c.name,
count: c.books.size # Using size instead of count is important since count will always query the DB
}
end
end # will query books count for each category.
def books_per_category2
categories.distinct.map do |c|
{
name: c.name,
count: c.books.count
}
end
end
end
Schemat bazy danych:
>
ActiveRecord::Schema.define(version: 20150508184514) do create_table "books", force: true do |t|
t.string "title"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "store_id"
end add_index "books", ["store_id"], name: "index_books_on_store_id" create_table "books_categories", id: false, force: true do |t|
t.integer "book_id", null: false
t.integer "category_id", null: false
end add_index "books_categories", ["book_id", "category_id"], name: "index_books_categories_on_book_id_and_category_id"
add_index "books_categories", ["category_id", "book_id"], name: "index_books_categories_on_category_id_and_book_id" create_table "categories", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end create_table "stores", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
end
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
2 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Spowoduje to następujące zapytanie SQL:
Anonimowy użytkownik
Potwierdzenie od:
wynikowy obiekt będzie miał teraz każdy atrybut instancji kategorii i będzie odpowiadał metodzie , która zwraca liczbę książek z tym identyfikatorem kategorii instancji.
W szczególności pozwoli ci to pominąć wszelkie kategorie, które nie są powiązane z książkami. jeśli chcesz je uwzględnić, zapytanie powinno zostać zaktualizowane do następujących: