2015-04-24 155 views
1

我有一個模型事件,它取決於執行,這取決於具有ProductTanlation的產品。 這個相同的事件模型有很多命令。 我想在表格中顯示的事件,並能夠通過計數(訂單),按名稱搜索排序他們... 我提出的SQL請求按模型組合的數量排序

select e.id, pt.name, nbc.nb 
from `events` as e 
inner join `executions` as ex on e.`execution_id` = ex.`id` 
inner join `products` as p on ex.`product_id` = p.`id` 
left outer join (select product_id, `name` from `product_translations` where `locale` ='en' group by `product_id` ) as pt on pt.`product_id` = p.id 
left outer join (select event_id, COUNT(*) as nb from orders group by event_id) as nbc on nbc.event_id = e.id 
where pt.name like '%plane%' 
order by 3 desc 

但我不能用它錄製ActiveRecord特別按順序排列(訂單)

順便說一下,我使用gem全球化爲我的翻譯。

回答

3

翻譯一個SQL查詢來Rails的方法,包括:

初始請求

select e.id, pt.name, nbc.nb 
from `events` as e 
inner join `executions` as ex on e.`execution_id` = ex.`id` 
inner join `products` as p on ex.`product_id` = p.`id` 
left outer join (select product_id, `name` from `product_translations` where `locale` ='en' group by `product_id` ) as pt on pt.`product_id` = p.id 
left outer join (select event_id, COUNT(*) as nb from orders group by event_id) as nbc on nbc.event_id = e.id 
where pt.name like '%plane%' 
order by 3 desc 

第一步 確定主表;這裏是Event。所以這是來自您的Event模型的電話。

Event 
    .select("events.id, pt.name, nbc.nb") 
    .joins("inner join `executions` as ex on events.`execution_id` = ex.`id` 
      inner join `products` as p on ex.`product_id` = p.`id` 
      left outer join (select product_id, `name` from `product_translations` where `locale` ='en' group by `product_id` ) as pt on pt.`product_id` = p.id 
      left outer join (select event_id, COUNT(*) as nb from orders group by event_id) as nbc on nbc.event_id = events.id") 
    .where("pt.name like '%plane%'") 
    .order("3 desc") 

第二步變換內連接到關係。您必須申報has_many/belongs_toExecutionProduct

Model Event < AR::Base 
    has_many :executions 
    has_many :products, :through => :executions 

Event 
    .select("events.id, pt.name, nbc.nb") 
    .joins(:products) 
    .joins("left outer join (select product_id, `name` from `product_translations` where `locale` ='en' group by `product_id`) as pt on pt.`product_id` = products.id 
      left outer join (select event_id, COUNT(*) as nb from orders group by event_id) as nbc on nbc.event_id = events.id") 
    .where("pt.name like '%plane%'") 
    .order("3 desc") 

子查詢出左外連接不能與目前的Rails 4來完成,但是你可以提取你的子查詢。

sub_query1 = ProductTranslation 
       .select("product_id, `name`") 
       .where("`locale` ='en'") 
       .group("`product_id`") 

sub_query2 = Order 
       .select("event_id, COUNT(*) as nb") 
       .group("event_id") 

Event 
    .select("events.id, pt.name, nbc.nb") 
    .joins(:products) 
    .joins("left outer join (#{sub_query1.to_sql}) as pt on pt.`product_id` = products.id 
      left outer join (#{sub_query2.to_sql}) as nbc on nbc.event_id = events.id") 
    .where("pt.name like '%plane%'") 
    .order("3 desc") 

其他一些校正 SQL命令是upcase,條件是哈希,更喜歡的錶款使用的表名。

sub_query1 = ProductTranslation 
       .select("`product_id`, `name`") 
       .where({ :locale => 'en' }) 
       .group(:product_id) 

sub_query2 = Order 
       .select("event_id, COUNT(*) as nb") 
       .group("event_id") 

Event 
    .select("#{Event.table_name}.id, pt.name, nbc.nb") 
    .joins(:products) 
    .joins("LEFT OUTER JOIN (#{sub_query1.to_sql}) AS pt 
      ON pt.`product_id` = #{Product.table_name}.id 
      LEFT OUTER JOIN (#{sub_query2.to_sql}) AS nbc 
      ON nbc.event_id = #{Event.table_name}.id") 
    .where("pt.name LIKE ?", '%plane%') 
    .order("3 DESC") 

Voilà!

+0

問題是我沒有ProductTranslation模型,因爲它由Globalize gem管理。 –