Mysql rails 4在has\ U MUN THRON关联上使用包含时保留连接对象顺序

Mysql rails 4在has\ U MUN THRON关联上使用包含时保留连接对象顺序,mysql,ruby,ruby-on-rails-4,eager-loading,Mysql,Ruby,Ruby On Rails 4,Eager Loading,使用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 :f

使用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是电影的集合,其成员通过join对象FilmCollectionFilm表示。FilmCollectionFilm有一个位置列,这样集合中的给定成员可以重新排序(像电影队列一样思考),因此我们需要连接对象,而不是has_和reasoned_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查询?

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

FilmCollection.includes(film_collection_films: :film)

如果你只做
FilmCollection.includes(:films)
,它会选择FilmCollectionFilms,然后扔掉它们。因此,上面的代码所做的工作量大致相同,但可以正确地构建查询。

尝试使用
联接
:FilmCollection.joins(:films)。首先。films?我实际上找到了一个解决方案,我将要发布。这可能会起作用,但我相信联接总体上比include慢,尤其是对于大型表。不过,我可能错了。注意:在我看来,这是一个只会在Rails 5中修复的bug:/Rails 3.2也可以使用。我还想指出,sql查询自己的
FilmCollection.includes(film\u collection\u films::film)
FilmCollection.includes(:films)
是相同的(用.to\u sql测试)。因此,在执行查询和构造数组之后,通过ruby的排序方法,我有根据地猜测了顺序是如何被保留的(无需深入activerecord代码)。这可能会导致性能下降,具体取决于记录的总数。为了满足我的需要,这是完美的!