5

mam dwa modele:Szyny - jak zamówić model według jego wielu skojarzeń?

#Product 
class Product < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
    attr_accessible :name 
    ... 
end 

#Category 
class Category < ActiveRecord::Base 
    has_and_belongs_to_many :products, :order => "name ASC" 

    attr_accessible :name, :priority 
end 

I chciałbym zamówić swoje produkty najwyższej kategorii priorytetowej, a następnie według nazwy produktów

Na przykład mam: 3 kategorie:

  • słodycze priorytetem = 3
  • owoce, priorytetu = 1
  • Desery priorytetu = 2

3 produkty:

  • lody czekoladowe, który ma desery i słodycze kategoriach
  • cookies, które ma desery i słodycze kategorii
  • Kiwi, który ma słodycze, owoce i desery kategorie

A ja je lubię zamawiać tak:

  • Kiwi (pierwsze dlatego owoce to najwyższy priorytet)
  • lody czekoladowe (drugi ponieważ czekolada jest przed ciasteczek i obaj mają kategorię z samym priorytecie)
  • Cookies

Jak może to zrobić w Railsach? Nie chcę moje produkty mają być powielane, wiem, że łatwo byłoby zrobić coś takiego:

Category.order("priority ASC").each do |cat| 
    cat.products.order("name ASC").each do |product| 
    end 
end 

Ale w tym przypadku kiwi, lody czekoladowe i Cookies będą powielane, ponieważ wszystkie one mają kilka kategorii . Czy istnieje prosty sposób na usunięcie duplikatów? A może istnieje sposób na zamówienie produktów bezpośrednio według kategorii o najwyższym priorytecie?

Edycja: więcej szczegółów na temat tego, co chcę osiągnąć

co chcę w rzeczywistości jest ogromny stół, gdzie po lewej stronie, mam wszystkie produkty (i tylko jedną linię za unikalny produkt) posortowane według kategorii ... Tak, że mogę mieć coś takiego:

  • Kategoria - Produkt
  • Fruit - Banana
  • Fruit - Apple
  • Fruit - Kiwi
  • desery - lody czekoladowe
  • desery - Cookies
  • słodkie - czekoladowe cukierki
  • Słodki - Apple Cukierki
  • ...

See? Nawet jeśli owoc jest deserowy i słodki, chcę, aby pojawił się tylko jeden raz w tym stole. I chcę, aby produkty pojawiały się w ich "najważniejszej" kategorii (dlatego też pomyślałem o "priorytecie").

W tym ogromnym stole będzie używany do edycji produktów, chcę być w stanie łatwo uzyskać dostęp do atrybutów wyrobu w (nie będzie jedna kolumna za atrybut). Naprawdę potrzebuję wykonać jak najmniej żądań bazy danych.


Dziękuję wszystkim, którzy mogą mi pomóc! Kulgar

Odpowiedz

7

Aby uniknąć duplikatów można spróbować tego,

Product.joins(:categories).group("products.name").order("categories.priority ASC, products.name ASC") 
+0

Spróbuję i dam ci znać, jeśli zadziała, dzięki! – Kulgar

+1

Dzięki! Twoje rozwiązanie wydaje się idealne do tego, co muszę zrobić. Naprawdę nie wiedziałem, że można użyć "grupy" do określonego atrybutu i używać go w ten sposób ... Zawsze uczysz się nowych rzeczy w magicznym świecie Rails! :) – Kulgar

1

Może spróbuj tego

products = Product.joins(:categories).order("categories.priority ASC, products.name ASC") 

ten pobiera wartości zduplikowanych również. Powiedzmy, że chcemy się pobrać nazwy, może można spróbować

products.map(&:name).uniq 
+0

Spróbuję i poinformować, czy to zadziałało, dzięki! – Kulgar

+0

Obydwie odpowiedzi zadziałały, ale dzięki shweta łatwiej uzyskać dostęp do atrybutów produktów. Głosuję, ponieważ twoje rozwiązanie działa dobrze! :) – Kulgar

+0

Chociaż grupowanie wygląda na eleganckie rozwiązanie, nie jestem do końca przekonany, czy jest skalowalny. Często zdaję sobie sprawę z tego, że potrzebuję ponad 2-3 parametrów z tego samego stołu. W tym przypadku, moim zdaniem, może być mądrze pobrać wszystkie kolumny w tablicy i używać go na całej stronie. To tylko jedno zapytanie :) Jeśli wywołasz grupę, inne zapytanie musiałoby zostać odpalone za każdym razem, gdy chcesz pobrać nowy atrybut. Biorąc to pod uwagę, jeśli jest to tylko nazwa, którą chcesz, grupa jest zdecydowanie bardziej eleganckim rozwiązaniem. Chciałbym, żeby ktoś mógł poddać krytyce mój proces myślenia. – Rahul