gpt4 book ai didi

mysql - 当通过关联在 has_many 上使用包含时,rails 4 保留连接对象顺序

转载 作者:可可西里 更新时间:2023-11-01 08:31:02 26 4
gpt4 key购买 nike

使用 Rails 4.1.6 和 Ruby 2.1.2 并给出以下三个对象:

class FilmCollection
has_many :film_collection_films, -> { order(:position) }
has_many :films, through: :film_collection_films
end

class FilmCollectionFilm
belongs_to :film_collection_film
belongs_to :film
end

class Film
has_many :film_collection_films
end

FilmCollections 是电影的集合,其成员通过连接对象 FilmCollectionFilm 表示。 FilmCollectionFilm 有一个位置列,因此集合的给定成员可以重新排序(就像电影队列一样),因此我们需要连接对象而不是 has_and_belongs_to_many。

当我尝试同时加载多个集合的电影时,我的问题出现了。

调用 FilmCollection.first.films 会得到如下查询:

SELECT `film_collections`.* FROM `film_collections`
ORDER BY `film_collections`.`id` ASC LIMIT 1
SELECT `films`.* FROM `films`
INNER JOIN `film_collection_films` ON `films`.`id` = `film_collection_films`.`film_id`
WHERE `film_collection_films`.`extensional_film_collection_id` = 1
ORDER BY `film_collection_films`.`position` ASC

根据连接对象中的位置正确排序电影。

而是调用 FilmCollection.includes(:films).first.films 会得到以下查询:

SELECT `film_collections`.* FROM `film_collections`
ORDER BY `film_collections`.`id` ASC LIMIT 1
SELECT `film_collection_films`.* FROM `film_collection_films`
WHERE `film_collection_films`.`film_collection_id` IN (1)
ORDER BY `film_collection_films`.`position` ASC
SELECT `films`.* FROM `films` WHERE `films`.`id` IN (1, 16, 53, 185)

它收集了正确的电影但忽略了查询第二部分中的顺序。当使用 .includes() 进行预加载但仍然没有 n+1 查询时,如何保留连接对象的顺序?

最佳答案

事实证明,您可以通过显式包含连接对象以及通过它的关联来解决此问题。下面的行将正确选择所有内容,并保留连接对象上存在的任何条件/顺序。

FilmCollection.includes(film_collection_films: :film)

如果您只执行 FilmCollection.includes(:films) 那么它无论如何都会选择 FilmCollectionFilms 然后扔掉它们。因此,上面的代码将完成大约相同数量的工作,但会正确构建查询。

关于mysql - 当通过关联在 has_many 上使用包含时,rails 4 保留连接对象顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27412477/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com