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