Rails 4关系没有被排序:' has_many'具有默认范围的关联,'包括'和'命令'链在一起

时间:2015-10-01 20:22:03

标签: ruby-on-rails sorting ruby-on-rails-4 has-many default-scope

我正在尝试使用默认范围在模型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  

使用命名范围,它确实有效。但是,这意味着我必须在表单构建器中添加一个参数才能使用该集合&#39; f.object.quiz_category_weights.sorted&#39;。

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

2 个答案:

答案 0 :(得分:0)

我认为使用&#39; includes&#39;具有默认范围,通常在Rails框架中或在我的Windows版本中。

但是,我发现使用&#39;加入&#39;确实有效。我没有使用QuizCategory中的任何其他属性,所以它也更适合我的用例:我只想使用&#39; sort_order&#39;来自连接表的属性。

固定代码是:

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

    belongs_to :quiz_category
end

答案 1 :(得分:0)

为关系引入了includes方法,为Rails提供了减少数据库查询的提示。它说:当您获取A类型的对象时,也会获取关联的对象,因为我以后需要它们,并且它们不应该逐个取出(the N+1 queries problem

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