2015-09-22 4 views
0
pry(main)> Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).order(created_at: "desc").last.statistics.map(&:state) 

2015-09-21 20:53:54,423|65310|DEBUG|development| - Loan Load (0.9ms) SELECT `loans`.* FROM `loans` INNER JOIN `statistics` ON `statistics`.`loan_id` = `loans`.`id` WHERE `loans`.`state` IN ('started', 'pending_declined') AND (`statistics`.`state` NOT IN ('prequalified', 'conditionally_approved', '4506t_results_uploaded', 'customer_forms_uploaded', 'ready_for_etran', 'etran_verified', 'forms_to_be_verified', 'forms_verified', 'credit_memo_entered', 'loandoc_generated', 'loandoc_completed', 'loandoc_customer_received_need_signatures', 'signatures_checked_and_uploaded', 'boarded')) ORDER BY `loans`.`created_at` ASC LIMIT 1 
2015-09-21 20:53:54,426|65310|DEBUG|development| - Statistic Load (0.3ms) SELECT DISTINCT `statistics`.* FROM `statistics` WHERE `statistics`.`loan_id` = 97 
=> ["started", "prequalified", "conditionally_approved", "customer_forms_uploaded", "ready_for_etran", "pending_declined"] 

Так, может быть, я не понимая, что происходит здесь ... Я прошу SQL, чтобы найти меня некоторые кредиты, где их статистика делать не содержат определенные значения. В этом примере я говорю, чтобы оставить без каких-либо кредитов с статистикой prequalified, но, как вы можете видеть из распечатки, статистика Loan # имеет prequalified, а также несколько других состояний, которые я хотел бы оставить ,Rails 4 .where.not

Может ли кто-нибудь пролить свет на это? Я сражался с ним часами, и в этот момент моя голова вращается.

ответ

0

С этого запроса ActiveRecord, у Вас есть:

  • Во-первых, нашел множество кредитов
  • следующий, заказанный created_at
  • затем, используемый в прошлом, чтобы найти предел 1 результат, находя старейший из числа

Итак, у вас есть экземпляр займа.

Поскольку вы вызвали #статистику по методу, я могу заключить, что кредит has_many :statistics, и вы нашли всю статистику, которая содержит значение внешнего ключа, которое соответствует экземпляру Loan, который вы нашли. Теперь у вас есть статистика.

Для набора статистики вы сопоставили их с атрибутом map.

Поскольку вы уже присоединились к статистике, попробуйте удалить .last.statistics из вашего запроса. Карта пользователя в результирующем наборе соответствует его состоянию. Кроме того, рассмотрите возможность использования #includes или # select.

0

Это потому, что вы используете last.statistics. Это означает, что результат по объекту кредита будет связан со статистикой, тогда как вы создали условие раньше. Посмотрите на свой последний результат запроса:

Statistic Load (0.3ms) SELECT DISTINCT `statistics`.* FROM `statistics` WHERE `statistics`.`loan_id` = 97 

удалить ваши last.statistics

Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).order(created_at: "desc").map(&:state) 

или , если вы хотите добавить условие, чтобы определить некоторые кредиты, которые вам нужно прежде, чем map(&state)

Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).where("loans.id IN (97)").order(created_at: "desc") 
0

Вы запрашиваете возврат продукта Loan и Statistic, так что он все еще возвращает Loan записей, которые имеют Statistic, у которого нет указанного состояния.

Если вы хотите только Loan, который не имеет Statistic на тех штатах, на все, что вы, вероятно, хотите, чтобы ваш SQL быть что-то по этой линии:

SELECT loans.*, 
    FROM loans 
LEFT OUTER JOIN (
    SELECT statistics.loan_id, COUNT(*) count 
    FROM quotes 
    WHERE statistics.state IN ('prequalified', 'conditionally_approved') 
     GROUP BY statistics.loan_id 
) statistics 
ON statistics.loan_id = loans.id 
WHERE loans.state IN ('started', 'pending_declined') 
AND statistics.count IS NULL; 

Мой SQLfu не то, что я бы гордиться так это возможно, не самый оптимизированный запрос, но он должен получить ожидаемый результат.

Вы можете конвертировать, что ActiveRecord интерфейс запросов, но, к сожалению подзапроса и LEFT JOIN на самом деле не поддерживается, по крайней мере, не в том смысле, что мы будем использовать это будет что-то вроде этого:

join_query = <<SQL 
    LEFT OUTER JOIN (
    SELECT statistics.loan_id, COUNT(*) AS count 
    FROM statistics 
    WHERE statistics.state IN (<<state>>) 
    ) statistics ON loans.id = statistics.loan_id 
SQL 

Loan 
    .joins(join_query) 
    .where(statistics: { count: null }) 
    .where(state: <<somestate>>) 
    .order(created_at: :desc) 

<<SQL ... SQL является Heredoc, кстати, если вы не знакомы с ним.

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