当没有数据要返回时,有没有办法忽略子查询?

时间:2013-02-14 09:50:37

标签: ruby-on-rails-3 rails-activerecord

我有以下查询:

Comic.join(:publishercomics).where("publisher_id = 1 AND (rating < 5 OR rating IS NULL) AND comics.id NOT IN (:favorites)", {:favorites => User.find_by_id(current_user_id).favorites.where("top_10 = true").map(&comic_id)})
当没有登录用户时,

current_user_id设置为0,否则设置为当前登录用户的ID。我试图这样做是因为我希望我不必编写两个查询,一个用于登录用户,另一个用于不登录。通常,能够编写一个跳过未找到记录这一事实的查询并停止尝试加入不存在的数据似乎很有用。如果我直接编写这个SQL,这将非常简单:

SELECT c.*
FROM comics c
INNER JOIN publishercomics pc ON pc.publisher_id = 1 AND pc.comic_id = c.id
WHERE comics.id NOT IN (SELECT comics_id FROM favorites WHERE user_id = current_user_id AND top_10 = true)
AND (c.rating < 5 OR c.rating IS NULL)

这个问题可能扩展到一般情况 - 有没有办法让rails查询的行为更像SQL,这样当查询的一部分没有返回数据时,整个查询不会失败?那么“User.find_by_id(0).favorites”只会返回没有记录?

2 个答案:

答案 0 :(得分:1)

尝试:

Comic.join(:publishercomics).where("publisher_id = 1 AND (rating < 5 OR rating IS NULL) AND comics.id NOT IN (:favorites)", {:favorites => User.find_by_id(current_user_id).nil? ? [0] : User.find_by_id(current_user_id).favorites.where("top_10 = true").map(&comic_id)})

user = User.find_by_id(current_user_id)
Comic.join(:publishercomics).where("publisher_id = 1 AND (rating < 5 OR rating IS NULL) AND comics.id NOT IN (:favorites)", {:favorites => user.nil? ? [0] : user.favorites.where("top_10 = true").map(&comic_id)})

答案 1 :(得分:0)

我发现此查询失败的另一种方式。如果用户存在,但没有与用户关联的收藏夹。

起初我尝试添加:

User.find_by_id(like_user_id).favorites.nil? ? [0]
像这样:

Comic.join(:publishercomics).where("publisher_id = 1 AND (rating < 5 OR rating IS NULL) AND comics.id NOT IN (:favorites)", {:favorites => User.find_by_id(current_user_id).nil? ? [0] : User.find_by_id(like_user_id).favorites.nil? ? [0] : User.find_by_id(current_user_id).favorites.where("top_10 = true").map(&comic_id)})

但这不起作用,因为'收藏'在某种程度上不是零。我不太明白这是如何工作的。所以我使用了:

User.find_by_id(like_user_id).favorites.count == 0 ? [0]

这似乎有效。