在相关列上订购

时间:2019-07-12 13:36:34

标签: ruby-on-rails postgresql activerecord

我有Modelhas_many ModelItemsModelItems belongs_to OtherModel的“代码”列。

我正在做这样的事情:

Model.find(1).model_items.includes(:other_model).order("other_model.code" :desc)

我正在尝试根据相关代码列的文本进行排序。

我什至尝试过:

ModelItems.where(model_id: 1).includes(:other_model).order("other_model.code" :desc)

我知道我需要在此处包含或加入,但是无论如何我都会得到此错误的变种:

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "other_model"

更新

这是一个不使用真实模型名称的例子。我一直都对。

包含是单数,订单模型名称必须是复数-为清楚起见,我们将other_model更改为widgit:

Model.find(1).model_items.includes(:widgit).order("widgits.code ASC")

2 个答案:

答案 0 :(得分:1)

添加引用

ModelItems
  .where(model_id: 1)
  .includes(:other_model)
  .references(:other_model)
  .order("other_model.code DESC")

答案 1 :(得分:1)

includes在这种情况下将执行2个查询以创建伪外部联接(也为preload),其概念如下

 SELECT * FROM model_items WHERE model_items.model_id = 1

 SELECT * FROM other_models WHERE other_models.model_item_id IN ( [IDS FROM PREVIOUS QUERY]) 

您可以通过以下几种方式强制执行单个查询:

  • eager_load-(ModelItems.eager_load(:other_model))当您在哈希查找器查询条件中引用了联接表或添加includes时,references的工作方式如下。

  • references-(ModelItems.includes(:other_model).references(:other_model))这将为eager_load

  • 强制执行include路径
  • where哈希查找器方法(ModelItems.includes(:other_model).where(other_models: {name: 'ABC'}))在这里includes聪明地意识到您已经为与other_model的关系设置了条件,并将自动创建联接因此查询不会格式错误。但是,这种查询表示为外部联接,但执行起来却像内部联接,效率较低*

但是,如果您不需要other_model中的信息,而只想将其用作排序机制,则可以使用joins(内部联接)或left_joins(外部联接)这将允许您对数据进行排序,但不会检索属性或实例化other_model关系下的相关对象

 ModelItems.joins(:other_model)
 # OR 
 ModelItems.left_joins(:other_model)  

*这些选项可以组合使用,在includes where哈希查找器方法的情况下,我也总是建议使用以下ModelItems.joins(:other_model).includes(:other_model).where(other_models: { name: 'ABC'})(INNER JOIN)。这将返回与ModelItems.includes(:other_model).where(other_models: {name: 'ABC'})(LEFT OUTER JOIN)相同的数据集,但是通过使用INNER JOIN,它变得比LEFT OUTER JOIN版本的效率更高

边注 order("other_models.code" :desc),这无效。取而代之的是,您需要在String中包括订购方向,或将StringSymbol设为例如(("other_models.code DESC")("other_models.code": :desc)