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).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”不会返回任何记录?

4

2 回答 2

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)})
于 2013-02-14T10:14:01.193 回答
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]

这似乎有效。

于 2013-02-15T07:16:19.357 回答