我有Model
个has_many
ModelItems
。 ModelItems
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")
答案 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
中包括订购方向,或将String
和Symbol
设为例如(("other_models.code DESC")
或("other_models.code": :desc)
)