Rails 4 关系未排序:'has_many' 带默认作用域的关联,'includes' 和 'order' 链接在一起
Rails 4 Relation is not being sorted: 'has_many' association w/ default scope, 'includes' and 'order' chained together
我正在尝试使用默认范围对模型 QuizCategoryWeight 施加排序顺序。目标是让@possible_answer.quiz_category_weights 到 return 的权重按排序顺序排列。
更新: 我已经将问题缩小到默认范围似乎对我有用的事实,只要它们只有 'order' 方法,但当 'includes' 方法与 'order' 方法链接时则不会。但是,这种链接确实适用于命名范围。
会不会是我的开发环境?或者这可能是 Rails 中的错误?
我正在使用 windows,所以这可能就是问题所在。目前在 ruby 2.0.0p645 (2015-04-13) [i386-mingw32] 和 Rails 4.2.4...
以下使用 QuizCategoryWeight 的默认范围似乎不起作用:
class QuizCategoryWeight < ActiveRecord::Base
#trying to use a default scope, but does not work
default_scope { includes(:quiz_category).order("quiz_categories.sort_order") }
belongs_to :possible_answer, inverse_of: :quiz_category_weights,
class_name: 'QuizPossibleAnswer', foreign_key: 'possible_answer_id'
belongs_to :quiz_category
end
class QuizPossibleAnswer < PossibleAnswer
has_many :quiz_category_weights,
#does not work whether the line below is used or not
->{ includes(:quiz_category).order("quiz_categories.sort_order") },
inverse_of: :possible_answer,
dependent: :destroy,
foreign_key: 'possible_answer_id'
end
class QuizCategory < ActiveRecord::Base
default_scope { order :sort_order }
end
有了命名范围,它确实有效。但是,这意味着我必须向我的表单构建器添加一个参数才能使用集合 'f.object.quiz_category_weights.sorted'.
class QuizCategoryWeight < ActiveRecord::Base
# named scope works...
scope :sorted, ->{ includes(:quiz_category).order("quiz_categories.sort_order") }
belongs_to :possible_answer, inverse_of: :quiz_category_weights,
class_name: 'QuizPossibleAnswer', foreign_key: 'possible_answer_id'
belongs_to :quiz_category
end
class QuizPossibleAnswer < PossibleAnswer
has_many :quiz_category_weights,
inverse_of: :possible_answer,
dependent: :destroy,
foreign_key: 'possible_answer_id'
end
我认为在 Rails 框架或我的 windows 版本中使用具有默认范围的 'includes' 存在错误。
不过,我发现使用 'joins' 确实有效。我没有使用 QuizCategory 中的任何其他属性,因此它也更适合我的用例:我只想使用连接的 table.
中的 'sort_order' 属性进行排序
固定码为:
class QuizCategoryWeight < ActiveRecord::Base
default_scope { joins(:quiz_category).order("quiz_categories.sort_order") }
belongs_to :quiz_category
end
为关系引入了 includes
方法,以提供 Rails 减少数据库查询的提示。它说:当你获取类型A的对象时,还要获取关联对象,因为我稍后需要它们,它们不应该一个一个地获取(the N+1 queries problem)
includes
最初是通过两个数据库查询实现的。首先是所有 A,然后是所有具有 A 中的一个 ID 的 B。现在 includes
经常使用 sql 连接来只有一个数据库查询。但这是一个内部优化。
这个概念是面向对象的,你想要来自 A 的对象,然后你通过 A 检索 B。所以我认为,如果你将包含的 B 的顺序设置回 A,你所做的比原始 includes
.
我正在尝试使用默认范围对模型 QuizCategoryWeight 施加排序顺序。目标是让@possible_answer.quiz_category_weights 到 return 的权重按排序顺序排列。
更新: 我已经将问题缩小到默认范围似乎对我有用的事实,只要它们只有 'order' 方法,但当 'includes' 方法与 'order' 方法链接时则不会。但是,这种链接确实适用于命名范围。
会不会是我的开发环境?或者这可能是 Rails 中的错误?
我正在使用 windows,所以这可能就是问题所在。目前在 ruby 2.0.0p645 (2015-04-13) [i386-mingw32] 和 Rails 4.2.4...
以下使用 QuizCategoryWeight 的默认范围似乎不起作用:
class QuizCategoryWeight < ActiveRecord::Base
#trying to use a default scope, but does not work
default_scope { includes(:quiz_category).order("quiz_categories.sort_order") }
belongs_to :possible_answer, inverse_of: :quiz_category_weights,
class_name: 'QuizPossibleAnswer', foreign_key: 'possible_answer_id'
belongs_to :quiz_category
end
class QuizPossibleAnswer < PossibleAnswer
has_many :quiz_category_weights,
#does not work whether the line below is used or not
->{ includes(:quiz_category).order("quiz_categories.sort_order") },
inverse_of: :possible_answer,
dependent: :destroy,
foreign_key: 'possible_answer_id'
end
class QuizCategory < ActiveRecord::Base
default_scope { order :sort_order }
end
有了命名范围,它确实有效。但是,这意味着我必须向我的表单构建器添加一个参数才能使用集合 'f.object.quiz_category_weights.sorted'.
class QuizCategoryWeight < ActiveRecord::Base
# named scope works...
scope :sorted, ->{ includes(:quiz_category).order("quiz_categories.sort_order") }
belongs_to :possible_answer, inverse_of: :quiz_category_weights,
class_name: 'QuizPossibleAnswer', foreign_key: 'possible_answer_id'
belongs_to :quiz_category
end
class QuizPossibleAnswer < PossibleAnswer
has_many :quiz_category_weights,
inverse_of: :possible_answer,
dependent: :destroy,
foreign_key: 'possible_answer_id'
end
我认为在 Rails 框架或我的 windows 版本中使用具有默认范围的 'includes' 存在错误。
不过,我发现使用 'joins' 确实有效。我没有使用 QuizCategory 中的任何其他属性,因此它也更适合我的用例:我只想使用连接的 table.
中的 'sort_order' 属性进行排序固定码为:
class QuizCategoryWeight < ActiveRecord::Base
default_scope { joins(:quiz_category).order("quiz_categories.sort_order") }
belongs_to :quiz_category
end
为关系引入了 includes
方法,以提供 Rails 减少数据库查询的提示。它说:当你获取类型A的对象时,还要获取关联对象,因为我稍后需要它们,它们不应该一个一个地获取(the N+1 queries problem)
includes
最初是通过两个数据库查询实现的。首先是所有 A,然后是所有具有 A 中的一个 ID 的 B。现在 includes
经常使用 sql 连接来只有一个数据库查询。但这是一个内部优化。
这个概念是面向对象的,你想要来自 A 的对象,然后你通过 A 检索 B。所以我认为,如果你将包含的 B 的顺序设置回 A,你所做的比原始 includes
.