首页 > 解决方案 > ActiveRecord 生成条件 SQL

问题描述

我编写函数的目标是允许调用者将相同的条件参数传递where给 ActiveRecord 中的调用,并且我想要相应的 Rails 生成的 SQL。

例子

如果我的函数接收到这样的哈希作为参数

role: 'Admin', id: [4, 8, 15]

我希望生成这个字符串

"users"."role" = 'Admin' AND "users"."id" IN (4, 8, 15)

可能的解决方案

我得到最接近的to_sql

pry(main)> User.where(role: 'Admin', id: [4, 8, 15])
=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"role\" = 'Admin' AND \"users\".\"id\" IN (4, 8, 15)"

它几乎完全返回了我想要的;但是,如果 SQL 的生成方式发生变化,我会更自在地不剥离SELECT ... WHERE自己。我意识到 WHERE 应该总是在那里分裂,但我更喜欢一种不那么脆弱的方法。

我的下一个方法是使用 Arel 的where_sql函数。

pry(main)> User.where(role: 'Admin', id: [4, 8, 15]).arel.where_sql
=> "WHERE \"users\".\"role\" = $1 AND \"users\".\"id\" IN (4, 8, 15)"

它摆脱了 ,SELECT但留下了WHERE。如果它已经注入了净化的角色,我会更喜欢它,但这使得它不太理想。

我也考虑过自己生成 SQL,但我宁愿避免这种情况。

你们有谁知道我眼皮底下有没有我还没找到的方法吗?还是有更好的方法来完全做到这一点?

Ruby  2.3.7
Rails 5.1.4

标签: ruby-on-rails-5arel

解决方案


我也想知道如何在没有领先的情况下获得条件WHERE。我在https://coderwall.com/p/lsdnsw/chain-rails-scopes-with-or中看到他们使用字符串操作来摆脱WHERE,这看起来很混乱,但可能是目前唯一的解决方案。:/

scope.arel.where_sql.gsub(/\AWHERE /i, "")


推荐阅读