这两种方法都可以:(还有更多)
.where(MyModel.arel_attribut(:id).eq(MyModel.arel_attribute(:id)))
# OR
.where(Arel.sql("1=1"))
这种“始终为真”的类型条件通常用于存储过程或字符串连接中的查询组装,在这种情况下,您总是有一个 WHERE 子句,但可能没有任何条件,例如
SET @sqlString = 'SELECT * FROM table WHERE 1=1'
IF (@var IS NOT NULL)
SET @sqlString = @sqlString + ' AND "column" LIKE ''%' + @var + '%'' '
EXEC (@sqlString)
# OR
sqlString = "SELECT * FROM table WHERE 1=1"
if someCondition
sqlString = sqlString + " AND column = " + value
end if
但所有这些似乎都过时了(尤其是在 Rails 方面)。
ActiveRecord 通过使用一个名为 Arel 的库来避免所有这些,该库在执行之前组装 SQL。
ActiveRecord 提供了一种方便的方法 (#all) 来生成类似的全选概念。您可以只调用MyModel.all,它将返回一个可链接的ActiveRecord::Relation,然后您可以应用条件,或者不应用条件,您可以添加 ORDER BY、GROUP BY、LIMIT、HAVING 等语句,这取决于您在代码中和运行时。
您可以利用这种可链接性来“组装”您认为合适的这些条件,例如
q = MyModel.all
q.where!(name: "engineersmnky") if find_my_name?
这些调用甚至不必在 SQL 语句顺序中产生“逻辑”意义,因为Arel 知道组合这些语句以形成连贯查询的顺序。例如
MyModel.having("COUNT(column) > 1")
.order(:name)
.group(:name)
.select("name, COUNT(column) AS counter")
.where(x: 12)
.limit(2)
从 SQL 的角度来看,这完全是混乱的,但是当实际查询被组装时,它将被正确排序。