2015-04-24 5 views
1

У меня есть модель Событие, которое зависит от исполнения, которое зависит от продукта, у которого есть ProductTanslation. У этой же модели событий есть много заказов. Я хотел бы, чтобы отобразить события в таблице и иметь возможность сортировать их по количеству (заказов), поиск по названию ... Я сделал запрос 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 

Но я не могу транскрибировать его ActiveReccord специально заказ по счету (заказы)

Кстати, я использую gem globalize для своих переводов.

ответ

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") 

Второй шаг Transform внутреннее соединение в отношениях. Вы должны объявить has_many/belongs_to до Execution и Product.

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, условия хэш, предпочитают использовать table_name для моделей таблицы.

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, потому что она управляется Gemlizeize. –

Смежные вопросы