2011-06-13 6 views
12

Tengo un método de clase en Usuario, que devuelve una complicada selección/unión/orden/límite al Usuario, y devuelve la relación. También aplica una cláusula where(:admin => true). ¿Es posible eliminar esta declaración particular de where, si tengo ese objeto de relación conmigo?Eliminar una cláusula 'where' de un ActiveRecord :: Relación

Algo así como

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

Respuesta

6

Podría hacer algo como esto (where_values tiene cada consulta where; tendría que ajustar el SQL para que coincida con la salida exacta de :admin => true en su sistema). Tenga en cuenta que esto sólo funcionará si no se ha ejecutado realmente la consulta todavía (es decir, no ha llamado .all en él, o utilizado sus resultados en una vista):

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

Sin embargo, estaría fuertemente recomendamos usar la respuesta de Emily para reestructurar el método complex_stuff.

10

no he encontrado una manera de hacer esto. La mejor solución es probablemente reestructurar su método existente complex_stuff.

En primer lugar, cree un nuevo método complex_stuff_without_admin que haga todo complex_stuff excepto por agregar el where(:admin => true). A continuación, vuelva a escribir el método complex_stuff para llamar al User.complex_stuff_without_admin.where(:admin => true).

Básicamente, solo acércate desde el lado opuesto. Agregue donde sea necesario, en lugar de llevarlo donde no lo necesite.

20

Sé que esto es una cuestión de edad, pero ya que los carriles 4 ahora se puede hacer esto

User.complex_stuff.unscope(where: :admin) 

Esto eliminará el dónde administrador parte de la consulta, si quiere unscope todo el where parte unconditinoally

User.complex_stuff.unscope(:where) 

PD: gracias a @Samuel por señalar mi error

+0

El método unscope no funciona así (más?): 'User.complex_stuff. unscope (donde:: admin) '(vea http://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-unscope) – Samuel

+0

Veo lo que quiere decir, revisaré esta noche y actualizaré mi responder. –

0

que tenía que hacer esto (Remove a 'where' clause from an ActiveRecord::Relation que estaba siendo creada por un alcance) al unir dos ámbitos, y lo hizo así: self.scope(from,to).values[:joins].

Quería unir valores de los dos ámbitos que componían el 'joined_scope' sin las cláusulas 'where', para poder agregar cláusulas 'where' alteradas por separado (alterado para usar 'OR' en lugar de 'AND')

Para mí, esto fue en el ámbito unido, así:

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

la esperanza de que ayude a alguien