Relacje miedzy obiektami a sortowanie listy

Zalozmy nastepujaca sytuacje:

  • tworzymy w bazie konta, poprzez ktore nastepuje system autoryzacji; typowa sytuacja, pola: id, login, haslo, osoba_id
  • tworzymy w bazie tabele osob, zakladam ze tylko czesc z osob ma tworzone konta (do celow administracyjnych); znowu typowo, pola: id, imie, nazwisko, email
  • tworzymy wszechpotezny i piekny backend, gdzie m.in. tworzymy liste kont; jednak nie chcemy ich listowac “po loginach”, lecz po imionach i/lub nazwiskach osob z kontami powiazanymi

Problem:
szukam sposobu na pobranie z bazy lsty kont posortowanych po imionach osob
chcialbym to zrobic poprzez operacje na modelu, bez uzywania sql-a i funkcji find_by_sql
chcialbym takze uniknac zbednego obciazania serwera sortowaniem tablicy

ot taki problem sobie uknulem

Za wszelkie sugestje bede bardzo wdzieczny

chcialbym to zrobic poprzez operacje na modelu, bez uzywania sql-a i funkcji find_by_sql
Mozesz zrobic tak
Konto.find(:first, :order => “imie”)
O to chodzi ?
Co i tak sprowadza sie do SQL. Po prostu musisz sie odwolac do bazy.

Jacek

Chodzi o sytuacje gdy masz relacje np. Person i Account i chodzi o to aby some_person.accounts potrafilo raz zwrocic liste kont posortowanych wg jedengo pola a drugi raz wg innego.
Dodam, ze nie chodzi o mnozenie relacji a o jakies w miare dynamiczne rozwiazanie.

[quote=balcer]Mozesz zrobic tak
Konto.find(:first, :order => “imie”)[/quote]
No wlasnie ze nie moge

Sytuacja wyglada dokladnie tak, ze Account i Person to dwie klasy ActiveRecord (tabele)
Zachodzi miedzy nimi relacja Account.person = Person.find(id)

Teraz gdy pobieram z bazy liste kont accounts = Account.find(:all) chcialbym ja otrzymac posortowana po atrybutach klasy Person, czyli np. Person.first_name

Jedyny sposob jaki przychodzi mi do glowy to accounts = Account.find_by_sql( i tu join i sortowanie po polach Person )

Jednak tak jak pisalem wyzej chcialbym tego uniknac, zrobic to w sposob ktorego idea sprowadza sie do; Account.find(:first, :order => Accoumt.person.first_name ) - jednak nie jest to tak banalne i sprawia mi problemy :slight_smile:

ale przecieÂż masz :joins, :select … nie wystarczy?

[quote=Marcin][quote=balcer]Mozesz zrobic tak

Jednak tak jak pisalem wyzej chcialbym tego uniknac, zrobic to w sposob ktorego idea sprowadza sie do; Account.find(:first, :order => Accoumt.person.first_name ) - jednak nie jest to tak banalne i sprawia mi problemy :)[/quote]
Mozesz to zrobic tak:
(jesli masz zdefiniowana relacje has_one, albo has_many na account i person)

Account.find(:first, :include=>:person, :order=>‘people.first_name’)

Odpal sobie tail -f development.log to zobaczysz co sie faktycznie dzieje w SQL’u

Powinno zadzialac (nie sprawdzalem)[/quote]

[quote=hosiawak]Mozesz to zrobic tak:
(jesli masz zdefiniowana relacje has_one, albo has_many na account i person)

Account.find(:first, :include=>:person, :order=>‘people.first_name’)[/quote]
hosiawak jestes wielki :slight_smile:
mam nadzieje ze bedzie to chodzic, o taka elegancje wlasnie mi chodzi :slight_smile:

jak bede mial chwilke zeby powrocic do tamtego projektu to sprawdze na pewno :slight_smile:

Oto rozwiazanie tego problemu:

@account_pages, @accounts = paginate( :accounts, :select => "accounts.*, accounts.id as id" , :joins => "INNER JOIN people ON accounts.person_id = people.id", :conditions => [ "accounts.published = ?", @if_to_list_published], :order => sql_order_by, :per_page => @items_per_page)
W wolnej chwili sprawdze rozwiazanie podane wyzej.

Faktycznie da sie zrobic to przez include ( nie iem tylko czy join jest INNER czy LEFT OUTER)

@account_pages, @accounts = paginate( :accounts, :include => :person, :select => "accounts.*, accounts.id as id" , :conditions => [ "accounts.published = ?", @if_to_list_published], :order => sql_order_by, :per_page => @items_per_page)

[quote]hosiawak napisał:

Mozesz to zrobic tak:
(jesli masz zdefiniowana relacje has_one, albo has_many na account i person)

Account.find(:first, :include=>:person, :order=>'people.first_name')[/quote]

Idealnie tego szukałem :)bardzo elegancka linijeczka.
Dzięki wielkie.