1

我正在尝试使用默认范围对模型 QuizCategoryWeight 施加排序顺序。目标是让@possible_answer.quiz_category_weights 按排序顺序返回权重。

更新: 我已经将问题缩小到这样一个事实,即默认范围似乎对我有用,只要它们只有一个“订单”方法,但当“包含”方法与“订单”方法链接时就不行。但是,此链接确实适用于命名范围。

会不会是我的开发环境?或者这可能是 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
4

2 回答 2

0

我认为在默认范围内使用“包含”存在一个错误,无论是在 Rails 框架中还是在我的 Windows 版本中。

但是,我发现使用“加入”确实有效。我没有使用 QuizCategory 中的任何其他属性,因此它也更适合我的用例:我只想使用连接表中的“sort_order”属性进行排序。

固定代码是:

class QuizCategoryWeight < ActiveRecord::Base
    default_scope { joins(:quiz_category).order("quiz_categories.sort_order") }

    belongs_to :quiz_category
end
于 2015-10-02T15:34:52.807 回答
0

includes方法是为关系引入的,旨在为 Rails 提供减少数据库查询的提示。它说:当你获取A类型的对象时,也要获取关联的对象,因为我以后需要它们,它们不应该一一获取(N+1查询问题

首先includes是通过两个数据库查询实现的。首先是所有 A,然后是所有具有 A 中一个 id 的 B。现在includes经常使用 sql join 来只有一个数据库查询。但这是内部优化。这个概念是面向对象的,你想要来自 A 的对象,然后你通过 A 检索 B。所以我认为,如果你将包含的 B 的顺序设置回 A,你所做的比原来的includes.

于 2015-10-02T22:19:40.820 回答