从ActiveRecord :: Relation中删除'where'子句

时间:2011-06-13 14:59:10

标签: ruby-on-rails activerecord

我在User上有一个类方法,返回对User应用复杂的select / join / order / limit,并返回该关系。它还应用where(:admin => true)子句。如果我有这个关系对象,是否可以删除这个特定的where语句?

这样的东西
User.complex_stuff.without_where(:admin => true)

5 个答案:

答案 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';

关键是名称列已被覆盖,但状态列已保留。