2009-10-18 12 views
13

Mam zapytanie, które przeszukuje dwa oddzielne pola w tej samej tabeli ... szuka lokalizacji, które najprawdopodobniej są konkretnym miastem, ale może też być krajem ... tj. potrzeba dwóch pól.hackowanie szyn, jak wyciągnąć dwa różne zapytania razem

Tabela wygląda następująco:

Country City 

Germany Aachen 
USA  Amarillo 
USA  Austin 

Wynik:

Keyword Sideinfo 

Aachen Germany 
USA  Country 
Austin USA 
Germany Country 

Zasadniczo Zastanawiam się, czy istnieje bardziej zwięzły sposób, aby to zrobić, ponieważ musiałem użyć dwóch oddzielnych zapytań następnie dodaj je razem, sortuj je itp. (co działa poprawnie):

def self.ajax(search) 
    countries = Location.find(:all, :select=> 'country AS keyword, "Country" AS sideinfo', :joins => :hotels, :conditions => [ 'hotels.email IS NOT NULL AND country LIKE ?', "#{search}%" ], :group => :country) 
    cities = Location.find(:all, :select=> 'city AS keyword, country AS sideinfo', :joins => :hotels, :conditions => [ 'hotels.email IS NOT NULL AND city LIKE ?', "#{search}%" ], :group => :city) 
    out = cities + countries 
    out = out.sort { |a,b| a.keyword <=> b.keyword } 
    out.first(8) 
    end 

Nie mogłem znaleźć żadnych informacji o tym, jak związki za pomocą ActiveRecord ...

+1

To pytanie jest dis cusses sposoby użycia lub fałszywe związki w ActiveRecord: http://stackoverflow.com/questions/6686920/activerecord-query-union –

Odpowiedz

7

Wykonanie zapytania UNION nie jest możliwe z ActiveRecord. Są więc dwa rozwiązania:

  • Użycie find_by_sql do budowania zapytania zgodnie z potrzebami. Nie radziłbym tego.
  • Używanie wtyczki takiej jak union do wykonania kwerendy UNION sql.
+4

Unia ma teraz 3 lata. Ktoś dostał bardziej aktualne rozwiązanie –

+0

@BillLeeper, chociaż twój komentarz został opublikowany w '12, sprawdź moją odpowiedź, jeśli nadal go szukasz –

+0

@BillLeeper https://github.com/brianhempel/active_record_union jest lepszym klejnotem. Używaj związków w zakresach ActiveRecord bez brzydoty. – lingceng

2

Używanie wtyczki Union, teraz działa pięknie podziękowań:

def self.ajax3(search) 
    Location.union([{ :select => 'city AS keyword, country AS sideinfo', 
         :joins => :hotels, 
         :conditions => [ 'email IS NOT NULL AND city LIKE ?', "#{search}%" ]}, 
        { :select => 'country AS keyword, "Country" AS sideinfo', 
         :joins => :hotels, 
         :conditions => [ 'email IS NOT NULL AND country LIKE ?', "#{search}%" ]}]) 
    end 
3

znalazłem schludny siekać użyciu wybierz. Na przykład, jeśli chcesz utworzyć związek między użytkownikiem a użytkownikiem innym użytkownikiem.

User.select('id from other_users union select id') 

ten wygeneruje ten SQL

"SELECT id from other_users union select id FROM users " 

Jeśli masz zakresów z warunkami można użyć ActiveRecord :: Relacja where_values ​​metoda

condition = OtherUser.example_condtion_scope.where_values.join(' ') 
User.select("id from other_users where #{contition}") 
1

Jest to obecnie możliwe w Rails 4 ,

locations = Location.arel_table 
hotels = Hotel.arel_table 

countries = Location 
       .select(locations[:country].as("keyword")) 
       .joins(:hotels) 
       .where(hotels[:email].not_eq(nil)) 
       .where(locations[:country].matches("#{search}%")) 

cities = Location 
      .select(locations[:city].as("keyword")) 
      .joins(:hotels) 
      .where(hotels[:email].not_eq(nil)) 
      .where(locations[:city].matches("#{search}%")) 

union = countries.union(cities) 

result = Location.from(locations.create_table_alias(union, :locations).to_sql) 
Powiązane problemy