2009-10-18 32 views
13

Tôi có truy vấn tìm kiếm hai trường riêng biệt trong cùng một bảng ... tìm kiếm các vị trí có khả năng nhất là thành phố cụ thể, nhưng cũng có thể là quốc gia ... tức là sự cần thiết cho hai lĩnh vực.rails union hack, cách lấy hai truy vấn khác nhau cùng nhau

Bảng trông giống như:

Country City 

Germany Aachen 
USA  Amarillo 
USA  Austin 

Kết quả:

Keyword Sideinfo 

Aachen Germany 
USA  Country 
Austin USA 
Germany Country 

Về cơ bản tôi đang tự hỏi nếu có một cách ngắn gọn hơn để làm điều này vì tôi đã phải sử dụng hai truy vấn riêng biệt sau đó thêm chúng cùng nhau, sắp xếp chúng, v.v. (hoạt động tốt):

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 

Tôi không thể tìm thấy bất kỳ thông tin nào về cách các công đoàn sử dụng ActiveRecord ...

+1

Câu hỏi này ngắt cusses cách để sử dụng hoặc các công đoàn giả trong ActiveRecord: http://stackoverflow.com/questions/6686920/activerecord-query-union –

Trả lời

7

Thực hiện truy vấn UNION không thể thực hiện được với ActiveRecord. Vì vậy, có hai giải pháp:

  • Sử dụng find_by_sql để tạo truy vấn nếu bạn muốn. Tôi sẽ không tư vấn cho nó.
  • Sử dụng plugin như union để thực hiện truy vấn sql UNION.
+4

Liên minh là 3 tuổi bây giờ. Bất kỳ ai có giải pháp cập nhật hơn –

+0

@BillLeeper mặc dù nhận xét của bạn đã được đăng trong '12, hãy kiểm tra câu trả lời của tôi trong trường hợp bạn vẫn đang tìm kiếm nó –

+0

@BillLeeper https://github.com/brianhempel/active_record_union là một loại đá quý tốt hơn. Sử dụng công đoàn trên phạm vi ActiveRecord mà không có sự xấu xí. – lingceng

2

Sử dụng các plugin đoàn, bây giờ nó làm việc tuyệt vời nhờ:

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

tôi thấy một hack gọn gàng sử dụng lựa chọn. Ví dụ: nếu bạn muốn kết hợp giữa Người dùng và Người dùng khác.

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

này sẽ tạo ra SQL này

"SELECT id from other_users union select id FROM users " 

Nếu bạn có phạm vi hợp với điều kiện bạn có thể sử dụng ActiveRecord :: Quan hệ where_values ​​phương pháp

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

này bây giờ là có thể trong 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) 
Các vấn đề liên quan