在编写了一些大型而复杂的SQL语句之后,我前段时间问我如何使用Rails以更好的方式做到这一点。但是,我最终再次使用了 Arel,因为如果我调用"find_by_sql",我无法嵌套更多条件。
Questions.find_by_sql(HUGE_SQL).by_filter(:popular).order('created_at').limit(5)
我的目标是:
- 在单独的文件中组织 sqls
- 将这些字符串 sqls 转换为 Arel 对象
- 将此 arel 对象嵌套为常见的可重用条件,例如"限制、顺序、."。
谢谢
解决方案是使用神奇的 scuttle.io 将复杂的SQL查询转换为Arel。然后,您可以为查询的每个部分创建单独的方法,并且仍然能够将它们组合在一起。本演示文稿中提供了更多详细信息。
我需要这样的东西,以便我可以从 Web 仪表板中获取筛选的范围并将其传递给后台任务,以使用相同的范围生成 CSV 导出。这是我想到的:
def sql_to_scope(model_class, sql)
model_class.from("(#{sql}) as "#{model_class.table_name}"")
end
给定一个Customer
模型:
sql_to_scope(Customer, Customer.where('id % 2 = 0').to_sql).find_each { |c| puts c.id }
# 2
# 4
# 6
sql_to_scope(Customer, "select * from customers where id % 2 = 0").pluck(:id)
# => [2, 6, 4]
它的工作原理是将默认的 FROM 子句替换为包含原始 SQL 的子查询。如果它在更复杂的情况下分崩离析,我不会感到惊讶,但它适用于我的简单需求。