我在User上有一个类方法,返回对User应用复杂的select / join / order / limit,并返回该关系。它还应用where(:admin => true)
子句。如果我有这个关系对象,是否可以删除这个特定的where
语句?
像
这样的东西User.complex_stuff.without_where(:admin => true)
答案 0 :(得分:26)
我知道这是一个老问题,但是因为rails 4现在你可以做到这一点
User.complex_stuff.unscope(where: :admin)
这将删除查询的where admin部分,如果你想取消整个where
部分unconditinoally
User.complex_stuff.unscope(:where)
ps:感谢@Samuel指出我的错误
答案 1 :(得分:10)
我还没有办法做到这一点。最好的解决方案可能是重构现有的complex_stuff
方法。
首先,创建一个新方法complex_stuff_without_admin
,除了添加complex_stuff
外,它会执行where(:admin => true)
所做的所有工作。然后重写complex_stuff
方法以调用User.complex_stuff_without_admin.where(:admin => true)
。
基本上,只是从对面接近它。在需要的地方添加,而不是在不需要的地方带走。
答案 2 :(得分:6)
您可以执行以下操作(where_values
保存每个where
查询;您必须调整SQL以匹配系统上:admin => true
的确切输出。请记住,这只有在您尚未实际执行查询时才会起作用(即您尚未在其上调用.all
或在视图中使用其结果):
@users = User.complex_stuff
@users.where_values.delete_if { |query| query.to_sql == "\"users\".\"admin\" = 't'" }
但是,我强烈建议使用Emily的答案来重构complex_stuff
方法。
答案 3 :(得分:0)
我需要在连接两个范围时执行此操作(Remove a 'where' clause from an ActiveRecord::Relation
由范围创建),并且这样做:self.scope(from,to).values[:joins]
。
我想加入组成' joined_scope'的两个范围的值。没有'其中'条款,以便我可以添加更改的' where'单独的条款(改为使用' OR'而不是' AND')。
对我来说,这就是联合范围,如下:
scope :joined_scope, -> (from, to) {
joins(self.first_scope(from,to).values[:joins])
.joins(self.other_scope(from,to).values[:joins])
.where(first_scope(from,to).ast.cores.last.wheres.inject{|ws, w| (ws &&= ws.and(w)) || w}
.or(other_scope(from,to).ast.cores.last.wheres.last))
}
希望能帮到某人
答案 4 :(得分:0)
这是一个古老的问题,虽然不能说出答案,但是rewhere确实存在。
从文档中:
允许您更改给定属性的先前设置的where条件,而不是附加到该条件。
类似这样:
Person.where(name: "John Smith", status: "live").rewhere(name: "DickieBoy")
将输出:
SELECT `people`.* FROM `people` WHERE `people`.`name` = 'DickieBoy' AND `people`.`status` = 'live';
关键是名称列已被覆盖,但状态列已保留。