2010-04-22 6 views
5

kłopoty z AR 2.3.5, npJak zmusić typ atrybutu ActiveRecord zwróconego przez: wybierz frazę na złączonym stole?

users = User.all(:select => "u.id, c.user_id", :from => "users u, connections c", 
     :conditions => ...) 

zwrotów, np

=> [#<User id: 1000>] 
>> users.first.attributes 
=> {"id"=>1000, "user_id"=>"1000"} 

Należy zauważyć, że AR zwraca id modelu poszukiwanej jako numeryczny ale wybrany user_id z połączonym modelu jako String, chociaż oba są int(11) w schemacie bazy danych.

W jaki sposób mogę lepiej utworzyć tego typu zapytanie, aby wybrać kolumny tabel wspierające wiele modeli i pobierające ich naturalny typ zamiast String? Wygląda na to, że AR ma gdzieś to robić. W jaki sposób mogę przymusić zwrócone typy w czasie ładowania AR i nie muszę nosić haseł .to_i (itp.) Na każdy dostęp post-hoc?

+1

Czy możesz wyjaśnić, co „połączenia”, i jak jest to związane z użytkowników? – kikito

Odpowiedz

1

Dlaczego używasz: z => "użytkowników" wewnątrz User.method? Poniższa zrobi sprzężenie wewnętrzne (czyli to, co robisz anyways)

users = User.all(:include => :connections, :select => "users.id, connections.user_id", :conditions => {...}) 

To będzie bardzo ciężki zapytań do bazy danych. Szybsze zapytanie byłoby jednak przy łączeniu zewnętrznym.

Będzie to również powrót klawiszy jako INT nie STRING

Znacznie szybsza alternatywa była

Connection.all(:include => :user, :conditions => {...}).collect {|e| [e.user_id, e.id] } 

Daje to szereg tablic z identyfikatorami. Jeśli wybierzesz tylko kolumny "id, user_id", niekoniecznie będzie to obiekt AR. Tablica może być szybsza.

Mam nadzieję, że nie brakuje mi tutaj jakiejś uwagi. Zaproponuj mi, jeśli tak.

+0

Opcja from from: została dodana do aliasu nazw kolumn tabeli. Podwarunki są mieszane dynamicznie. Rozważę twoje podejście i zrobię z nim test - dzięki. – tribalvibes

2

Niestety nie będzie to łatwe. Wszystkie dane z połączenia DB przychodzą do szyn jako łańcuchy, a konwersja typów odbywa się w każdej dynamicznej metodzie atrybutu tworzonej przez szyny w środowisku wykonawczym. Wie, które atrybuty konwertować do jakiego typu według metadanych kolumn typu tabeli, które pobiera po uruchomieniu aplikacji. Każdy model zawiera tylko meta-dane kolumny dla własnych kolumn, dlatego własne kolumny kończą się prawidłowym typem. Nie ma łatwego sposobu automatycznego przekonwertowania na odpowiednie typy.

Z drugiej strony można utworzyć prostą metodę konwersji, która będzie miała skrót i automatycznie przekształcić atrybuty.

coś takiego:

users = User.all(:select => "cl, comments.c2", ...) 
users = convert_columns(users, 'c2' => :integer, 'other_column' => :date) 

def convert_columns(records, columns = {}) 
    records.each do |rec| 
    columns.each do |col, type| 
     rec[col] = case type 
     when :int then rec[col].to_i 
     when :date then ........ 
     .... 
     end 
    end 
    end 
end 
0

Jeśli chcesz szybkiego rozwiązania - spróbuj użyć after_find zwrotnego i ustawione poprawne typy atrybutów tam:

class User < ActiveRecord::Base 

    after_find :preset_types 


    private 
    def preset_types user 
    user.user_id = user.user_id.to_i 
    end 

end 
Powiązane problemy