Вложенные SQL-запросы в рельсы, когда: has_and_belongst_to_many - PullRequest
1 голос
/ 09 января 2011

В моем приложении I следующая задача, которая еще не была выполнена пользователем. У меня есть три модели: A Книга , в которой есть много Задач , а затем у меня есть Пользователь , который имеет и принадлежит ко многим задачам. Таблица tasks_users содержит все выполненные задачи, поэтому мне нужно написать сложный запрос, чтобы найти следующую задачу для выполнения.

Я предложил два решения на чистом SQL, которые работают, но я не могу перевести их на рельсы, вот что мне нужно помочь с

SELECT * FROM `tasks`
WHERE `tasks`.`book_id` = @book_id
AND `tasks`.`id` NOT IN (
    SELECT `tasks_users`.`task_id`
    FROM `tasks_users`
    WHERE `tasks_users`.`user_id` = @user_id)
ORDER BY `task`.`date` ASC
LIMIT 1;

и в равной степени без вложенного выбора

SELECT *
FROM tasks
LEFT JOIN tasks_users
    ON tasks_users.tasks_id = task.id
    AND tasks_users.user_id = @user_id
WHERE tasks_users.task_id IS NULL
AND tasks.book_id = @book_id
LIMIT 1;

Это то, что я сделал в рельсах с плагином MetaWhere

book.tasks.joins(:users.outer).where(:users => {:id => nil})

но я не могу понять, как получить туда текущего пользователя,

Спасибо за любую помощь!

Ответы [ 2 ]

1 голос
/ 09 января 2011

Я думаю, что это будет дублировать вторую форму с левым соединением:

class Task < ActiveRecord::Base
  scope :next_task, lambda { |book,user| book.tasks.\
    joins("LEFT JOIN task_users ON task_users.task_id=tasks.id AND task_users.user_id=#{user.id}").\
    where(:tasks=>{:task_users=>{:task_id=>nil}}).\
    order("date DESC").limit(1) }
end

Обратите внимание, что вместо tasks_users используется имя таблицы task_user, что более типично для модели соединения. Кроме того, он должен быть вызван с:

Task.next_task(@book_id,@user_id)
0 голосов
/ 09 января 2011
book.tasks.where("tasks.id not in (select task_id from tasks_users where user_id=?)", @user_id).first

Это даст вам первую задачу, у которой еще нет записи в tasks_users для текущего пользователя.

...