我有一个ImageCollection类,其状态可以为“活动”。此类属于一个Image,该Image具有一个名为“ workflow_state”的属性。
我有以下可行的方法,但要花几秒钟才能完成:
def self.published
where(status: STATUS_ACTIVE).select { |x| x.image.workflow_state == Publishable::Meta.published_key }
end
以下内容无效:
scope :published, lambda {
where(status: STATUS_ACTIVE).joins(:image).where(
'image.workflow_state = ?', Publishable::Meta.published_key
)
}
并返回:
ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'image.workflow_state' in 'where clause': SELECT `image_containers`.* FROM `image_containers` INNER JOIN `images` ON `images`.`id` = `image_containers`.`image_id` WHERE `image_containers`.`status` = 'active' AND (image.workflow_state = 'published') ORDER BY `image.containers`.`id` ASC LIMIT 1
我很困惑,因为图像表具有工作流程状态
非常感谢您的帮助
答案 0 :(得分:2)
如果您使用纯SQL,则应使用复数表名。
更改:将image.workflow_state
更改为images.workflow_state
答案 1 :(得分:2)
我有以下可行的方法,但要花几秒钟才能完成:
来自self.published
方法的查询将提取所有带有status: STATUS_ACTIVE
的记录,然后扫描结果数组,以获取给出image.workflow_state
的那些记录。因此,它获取将被select
丢弃的结果,这是浪费资源。更糟糕的是,它为每一行创建一个ActiveRecord对象,并向数据库发出附加请求以获取其image
关联。这是臭名昭著的N + 1 pattern problem。
要解决此问题,您需要将查询重写为
joins(:image).where(status: STATUS_ACTIVE, images: { workflow_state: Publishable::Meta.published_key } )