2011-01-09 89 views
1

在我的应用程序中,下一个任务尚未由用户完成。我有三个模型,A ,有很多任务,然后我有一个用户已拥有和属于许多任务。表tasks_users表包含所有完成的任务,所以我需要编写一个复杂的查询来查找下一个要执行的任务。在rails中嵌套sql查询时:has_and_belongst_to_many

我已经想出了在工作的纯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}) 

但我不能了解如何获得当前用户,

感谢您的帮助!

回答

1

我认为这将复制与左边的第二种形式加盟:

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.next_task(@book_id,@user_id) 
+0

谢谢,这是我想到的东西了。非常丑陋与这么多硬编码SQL,但它的作品。 – Godisemo 2011-01-11 15:25:49

0
book.tasks.where("tasks.id not in (select task_id from tasks_users where user_id=?)", @user_id).first 

这会给你第一个任务,在当前用户的tasks_users中没有条目。