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

Dog*_*ert 15 activerecord ruby-on-rails

我在User上有一个类方法,返回对User应用复杂的select/join/order/limit,并返回关系.它还适用一个where(:admin => true)条款.where如果我有这个关系对象,是否有可能删除这个特定的陈述?

就像是

User.complex_stuff.without_where(:admin => true)
Run Code Online (Sandbox Code Playgroud)

Moh*_*ady 28

我知道这是一个老问题,但是因为rails 4现在可以做到这一点

User.complex_stuff.unscope(where: :admin)
Run Code Online (Sandbox Code Playgroud)

这将删除查询的where管理部分,如果你想unconditinoally取消整个where部分

User.complex_stuff.unscope(:where)
Run Code Online (Sandbox Code Playgroud)

ps:感谢@Samuel指出我的错误


Emi*_*ily 10

我还没有办法做到这一点.最好的解决方案可能是重构现有complex_stuff方法.

首先,创建一个新方法complex_stuff_without_admin,complex_stuff除了添加之外,它还可以执行所有操作where(:admin => true).然后重写complex_stuff要调用的方法User.complex_stuff_without_admin.where(:admin => true).

基本上,只是从对面接近它.在需要的地方添加,而不是在不需要的地方带走.


Dic*_*Boy 7

这是一个老问题,这并不能回答每个问题,但rewhere是存在的。

从文档中:

允许您更改给定属性的先前设置的 where 条件,而不是附加到该条件。

所以像这样:

Person.where(name: "John Smith", status: "live").rewhere(name: "DickieBoy")
Run Code Online (Sandbox Code Playgroud)

将输出:

SELECT `people`.* FROM `people` WHERE `people`.`name` = 'DickieBoy' AND `people`.`status` = 'live';
Run Code Online (Sandbox Code Playgroud)

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


Dyl*_*kow 6

您可以执行类似这样的操作(where_values保存每个where查询;您必须调整SQL以匹配:admin => true系统上的确切输出).请记住,这只有在您尚未实际执行查询时才会起作用(即您尚未调用.all它,或在视图中使用其结果):

@users = User.complex_stuff
@users.where_values.delete_if { |query| query.to_sql == "\"users\".\"admin\" = 't'" }
Run Code Online (Sandbox Code Playgroud)

但是,我强烈建议使用Emily的重组complex_stuff方法的答案.