我有一个ActiveRecord请求:
Post.all.select { |p| Date.today < p.created_at.weeks_since(2) }
我希望能够使用.to_sql查看它生成了什么SQL请求我得到的错误是:NoMethodError: undefined method 'to_sql'TIA!
.to_sql
NoMethodError: undefined method 'to_sql'
0x6upsns1#
版本
当涉及ActiveRecord对象时,有两种select类型,来自文档
ActiveRecord
select
Array#select
Post
Array
where
order
to_sql
建议的解决方法:
相反,您需要的是一个WHERE子句,用于在将记录返回到ORM之前在数据库级别筛选记录。您当前的筛选器为(X〈Y + 2)
Date.today < p.created_at.weeks_since(2)
这意味着“今天的日期”小于“创建时间”加上2周。我们可以反转此条件,将其切换为“今天的日期减去2周”小于“创建时间”(X - 2〈Y),从而使查询更容易。
Date.today.weeks_ago(2) < p.created_at
这相当于p.created_at > Date.today.weeks_ago(2),我们可以使用标准ActiveRecord查询方法将其转换为where子句:
p.created_at > Date.today.weeks_ago(2)
Post.where(created_at: Date.today.weeks_ago(2)...)
这将产生如下SQL:
SELECT posts.* FROM posts.* WHERE posts.created_at > '2022-10-28'
备注:
created_at
Time.now
Date.today
ni65a41a2#
你需要在一个关系上调用to_sql。select执行查询并给你结果,在结果上你没有to_sql方法。有类似的questions,你可以看看,因为他们提供了一些替代品。
2条答案
按热度按时间0x6upsns1#
版本
当涉及
ActiveRecord
对象时,有两种select
类型,来自文档select
与块。首先:取一个块,这样就可以像
Array#select
一样使用它。这将为作用域从数据库中构建一个对象数组,将它们转换为数组,并使用
Array#select
遍历它们。这就是你现在正在使用的。这个实现将加载每个post示例化一个
Post
对象,然后使用Array#select
迭代每个Post
,将结果过滤到一个Array
中。这是非常低效的,不能与其他AR语义链接(例如where
、order
等),并将导致很长的规模滞后。(这也是导致错误的原因,因为Array
没有to_sql
方法)select
与列列表(如果愿意,也可以是String)第二:修改查询的SELECT语句,以便只检索某些字段...
在您的情况下不需要此版本,因为您不希望将查询返回的列限制为帖子。
建议的解决方法:
相反,您需要的是一个WHERE子句,用于在将记录返回到ORM之前在数据库级别筛选记录。
您当前的筛选器为(X〈Y + 2)
这意味着“今天的日期”小于“创建时间”加上2周。
我们可以反转此条件,将其切换为“今天的日期减去2周”小于“创建时间”(X - 2〈Y),从而使查询更容易。
这相当于
p.created_at > Date.today.weeks_ago(2)
,我们可以使用标准ActiveRecord查询方法将其转换为where子句:这将产生如下SQL:
备注:
created_at
是时间戳,因此使用Time.now
与Date.today
可能更好。ni65a41a2#
你需要在一个关系上调用
to_sql
。select
执行查询并给你结果,在结果上你没有to_sql
方法。有类似的questions,你可以看看,因为他们提供了一些替代品。