Sortowanie z asocjowanych modeli

Witam wszystkich serdecznie.
Zacząłem przygodę z sortowaniem wyników zapytań do modelu ( http://railscasts.com/episodes/228-sortable-table-columns ) oczywiście pojawiły się pewne zawiłości składniowe.

Mianowicie mam modele ‘Buildings’ i ‘CostBuildings’ połączone ze sobą 1:1 (has_one, belongs_to)
Tabela ‘Buildings’ ma kolumny ‘name’ , ‘description’ , natomiast ‘CostBuildings’ ‘building_id’ i ‘cost’
Chciałym zebrać wszystkie budynki posortowane po cenie.
Składnia:

 @building = Building.costBuilding.order('cost ASC')

oczywiście nie ma prawa zadziałać.
Najrozsądniej wydaje mi się że powinno być:

 @building = Building.order('cost_buildings.cost ASC')

niestety

Korzystając z zapytania SQL połączył bym pewnie tabele poleceniem JOIN i wydawało by się ok.
Wydawać by się mogło (mylnie?) że zrobi to za mnie polecenie has_one, belongs_to w Modelach.
Prosiłbym o jakąś wskazówkę jak mógłbym rozwiązać ten problem.

jak chcesz posortować obiekty to musisz użyć metody find czyli

Building.find :all, :include => :cost_building, :order => 'cost_buildings.cost ASC'

Powyższy kod zwróci ci wszystkie rekordy budynków posortowane wg ceny.

świetnie podany kod działa poprawnie jednakże chciałbym osiągnąć coś podobne za pomocą krótszej składni typu:

@building = Building.all.costBuilding.order('cost ASC')

ułatwiło by mi to pisanie motody helpera która odwalała by całą robotę za mnie.

W takim razie wpisujesz Building.all(:include => :cost_building, :order => 'cost_buildings.cost ASC')
ale osobiście użyłbym składni bez nawiasów czyli Building.all :include => :cost_building, :order => 'cost_buildings.cost ASC'
Poczytaj sobie http://apidock.com/rails/ActiveRecord/Base/find/class

Gdyby ktoś miał podobny problem to rozwiązaniem może być:
Controller

[code]class Admin::BuildingsController < ApplicationController
helper_method :sort_column, :sort_direction, :sort_include
def index
@buildings = SysBuilding.all :include => sort_include, :order => sort_column+’ '+sort_direction
end

private

def sort_include
%w[sysCostBuilding].include?(params[:inc]) ? params[:inc] : nil
end
def sort_column
%w[name description nation_id sys_cost_buildings.cost1].include?(params[:sort]) ? params[:sort] : “name”
end

def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : “asc”
end
end[/code]
Helper:

module ApplicationHelper def sort_col(column,title = nil,include = nil) title||=column.titleize dir = column == sort_column && sort_direction == "asc" ? "desc" : "asc" link_to title, {:sort => column , :direction => dir, :inc=>include} end end
View:

[code]

<% end %>
<%= sort_col "name" %> <%= sort_col "description" %> <%= sort_col "sys_cost_buildings.cost1", "waluta", "sysCostBuilding"%>
<th></th>

<% @buildings.each do |building| %>

<%= building.name %> <%= building.description %> <% =.... currency ... %> <%= link_to 'Show', :action=> :show ,:id=>building %>
<%= link_to 'Edit', edit_admin_building_path(building) %>
[/code]

[quote=wafcio]ale osobiście użyłbym składni bez nawiasów czyli Building.all :include => :cost_building, :order => 'cost_buildings.cost ASC'
Poczytaj sobie http://apidock.com/rails/ActiveRecord/Base/find/class[/quote]
Warto tak spróbować bo imo czytelniej:

Building.include(:cost_buildings).order(:cost)

O to wygląda bardzo przejrzyście i wydaje mi się że takie są zalecenia dot . Rails 3 a propos zapisywania kodu.
Dzięki wam wszystkim za szybką pomoc :slight_smile:

Zmodyfikowany, działający kod Controllera dla powyższego przykładu:

 @buildings = Building.includes(sort_include).order(sort_column+' '+sort_direction)

[quote=mleszcz]Building.include(:cost_buildings).order(:cost)
[/quote]
Jeśli można się jeszcze wtrącić, to mógłbyś podać jakieś dokumentację API do tego co napisałeś, bo ja tego nie znalazłem.

Active Record Query Interface