2017-08-17 46 views
-1

存在於關聯中的訂單元素,其中第一個元素將是存在於最多選定關聯中的元素。 換句話說,按給定列表存在大多數assosietions的順序元素。 聽起來很複雜,所以在這裏的工作示例,但超級慢。Rails通過大多數條件的訂單記錄符合

我們希望將汽車進行排序,以最驅動器可驅動他們

# we have some ids of driver seleted by user 
dynamic_drivers_ids = [1,2,3,100,5] 

@cars = Car.all.includes(:driving_levels) 
@cars.sort_by {|e| (e.driving_level.map(&:driver_id) & dynamic_drivers_ids).size * -1 } 

需要大約1個第二加載,只有20輛。 但現在我們有100輛車的情況,並且需要數十年來計算它。

我們如何編寫SQL請求來訂購? 它不工作,但顯示出一些邏輯:

Car.includes(:driving_levels).order("driving_level.id IN = ? AND driving_level.size", dynamic_drivers_ids) 

數據庫表的樣子:

class Car 
    has_many :driving_levels 
    has_many :drivers, through: driving_levels 


class DrivingLevel 
    belongs_to :car 
    belongs_to :driver 

class Driver 
    has_many :driving_levels 
    has_many :cars, through: driving_levels 
+0

你的db是什麼? –

+0

看來'汽車belongs_to driving_level'。所以看到'driving_level.map(&:driver_id)'很奇怪。請提供型號代碼。 –

+0

我已更新表格 – GEkk

回答

0

什麼左加入driving_levels但只有那些在dynamic_drivers_idsdriver_id(希望dynamic_drivers_ids不來自用戶,否則它是sql-injection-prone)?那麼你可以根據駕駛等級的數量進行分組和排序?

這將是這樣的:

Car 
    .joins("LEFT OUTER JOIN driving_levels ON 
      driving_levels.id = cars.driving_level_id AND 
      driving_level.driver_id IN (#{dynamic_drivers_ids})") 
    .group(:id).order("COUNT(driving_levels.id)") 
+0

不知道你是否可以插入數組到SQL字符串:( – GEkk

+0

是的,我的錯誤,你需要編輯 –

0

首先,你應該使用wherereferences這裏:

dynamic_drivers_ids = [1,2,3,100,5] 

@cars = Car.includes(:driving_level). 
      references(:driving_level). 
      where(driving_level: {id: dynamic_drivers_ids}) 

這裏發生的是它將連接表carsdriving_level,和只拉driving_level記錄,其中包含這些ID(您不需要做:e.driving_level.map(&:driver_id) & dynamic_drivers_ids)。你不會再把所有的driving_level記錄全部取出​​來。 這應該大大加快。

次要:按關聯排序。最簡單的方法是在它使用的列,其計算我們的協會,然後順序:

@cars = Car.select('COUNT(driving_levels.id) as driving_levels_size'). 
      includes(:driving_level). 
      references(:driving_level). 
      where(driving_level: {id: dynamic_drivers_ids}). 
      group('cars.id, driving_levels.id'). 
      order('driving_levels_size') 

這應返回你正確的順序和關聯設定的正確的記錄。

+0

有一個錯誤PG :: UndefinedColumn:錯誤:列「driving_levels_size」不存在 – GEkk

0

如果driving_levels包含driver_id 1,2,3,100,5的記錄,請嘗試此操作。

select_clause = <<~SQL 
    cars.*, 
    (SELECT count(DISTINCT driver_id) FROM driving_levels 
    WHERE driver_id IN (1,2,3,100,5) 
     OR car_id=cars.id) as driver_cnt 
SQL 

Car 
    .select(select_clause) 
    .order('driver_cnt DESC') 
    .to_a