Удалить предложение "where" из ActiveRecord:: Relation

У меня есть метод класса для пользователя, который возвращает для пользователя сложный параметр select/join/order/limit и возвращает отношение. Он также применяет предложение where(:admin => true). Можно ли удалить этот конкретный оператор where, если у меня есть этот объект отношения со мной?

Что-то вроде

User.complex_stuff.without_where(:admin => true)

Ответ 1

Вы можете сделать что-то вроде этого (where_values содержит каждый запрос where, вам нужно будет настроить SQL для точного вывода :admin => true в вашей системе). Имейте в виду, что это будет работать, только если вы еще не выполнили запрос (т.е. Вы не написали .all на нем или использовали его результаты в представлении):

@users = User.complex_stuff
@users.where_values.delete_if { |query| query.to_sql == "\"users\".\"admin\" = 't'" }

Однако я настоятельно рекомендую использовать ответ Эмили о реструктуризации метода complex_stuff.

Ответ 2

Я знаю, что это старый вопрос, но с рельсов 4 теперь вы можете это сделать

User.complex_stuff.unscope(where: :admin)

Это приведет к удалению части запроса администратора, если вы хотите обнулить целую часть where unonditinoally

User.complex_stuff.unscope(:where)

ps: спасибо @Samuel за указание моей ошибки

Ответ 3

Я не нашел способ сделать это. Лучшим решением, вероятно, является реструктуризация существующего метода complex_stuff.

Сначала создайте новый метод complex_stuff_without_admin, который делает все complex_stuff, кроме добавления where(:admin => true). Затем перепишите метод complex_stuff для вызова User.complex_stuff_without_admin.where(:admin => true).

В принципе, просто подходите к нему с противоположной стороны. Добавьте туда, где это необходимо, вместо того, чтобы отбирать, где не нужно.

Ответ 4

Мне нужно было сделать это (Remove a 'where' clause from an ActiveRecord::Relation, который создавался с помощью области видимости), в то время как он соединялся с двумя областями, и сделал это следующим образом: self.scope(from,to).values[:joins].

Я хотел объединить значения из двух областей, которые составляли "join_scope" без предложений "where", чтобы я мог добавлять измененные предложения "where" отдельно (изменено для использования "ИЛИ" вместо "И" ).

Для меня это произошло в объединенной области, например:

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))
}

Надеюсь, что кто-то поможет