2010-01-15 6 views
19

Dans mon modèle post.rb, j'ai default_scope :conditions => {:deleted => 'false'}default_scope dans Rails Redéfinition

Mais si je tente d'exécuter Post.find(:all, :conditions => "deleted='false'"), il ne retournera rien. C'est comme si le default_scope avait la priorité sur tout.

Je le veux pour que quand je le fais Post.find() il ne retourne pas les messages supprimés, mais j'aimerais aussi pouvoir y accéder si j'en ai besoin. Qu'est-ce qui doit être changé dans ma requête ou dans mon modèle Rails?

Merci.

+0

'default_scope' * a * la priorité sur tout. J'ai écrit une réponse en utilisant 'named_scope' à votre question précédente que je pense serait également applicable ici: http://stackoverflow.com/questions/2073197/how-to-get-a-model-to-specify-a- Les pré-requis-conditions/2073858 # 2073858 – jerhinesmith

Répondre

17

with_exclusive_scope est protected, vous devez donc créer une méthode de classe:

def self.include_deleted_in 
    Event.with_exclusive_scope { yield } 
end 

puis dans l'appel du contrôleur

Post.include_deleted_in { Post.find(:all) } 
+0

+1; Merci - meilleure réponse que j'ai trouvé dans le réseau – Makibo

+0

Event.with_exclusive_scope {yield} n'a pas fonctionné pour moi, j'ai dû mettre Post.with_exclusive_scope {yield}. Quoi qu'il en soit, bonne réponse. Sauve ma vie aujourd'hui. – workdreamer

1

utilisation with_exclusive_scope

Post.with_exclusive_scope { Post.find(:all) } 
+0

L'utilisation de ceci (en dehors du modèle Post) entraîne: méthode protégée 'with_exclusive_scope 'appelée pour # intepid

+0

Vous pouvez utiliser' Post.send (: with_exclusive_scope) {.. .} ' –

1

Scopes sont censés être composables, ce qui signifie que vous pouvez combiner un tas d'entre eux et il applique effectivement toutes les conditions. Dans ce cas, ActiveRecord est trop naïf pour déterminer que la condition explicite doit annuler le premier. Il construit simplement la requête rejoignant toutes les clauses avec ANDs. Pour cette raison default_scope a le plus d'utilité avec les clauses: order qui n'est pas composable (dans l'implémentation d'ActiveRecord 2.3 de toute façon). Il y a plus de discussion here.

Notez également que dans Rails 3, ActiveRecord utilise Arel pour beaucoup de construction de requêtes, ce qui augmentera considérablement la puissance de la génération de requêtes ActiveRecord tout en simplifiant beaucoup d'internes. Il est probable qu'avec Arel, vous améliorerez votre situation. En attendant, je recommande de ne pas mettre de conditions dans un default_scope à moins qu'il n'y ait des lignes que vous voulez vraiment être invisible pour votre application Rails.

60

Celui-ci était en quelque sorte gauche caché :)

Il suffit d'utiliser Post.unscoped.where(:deleted => true), si vous utilisez Rails 3

Le crédit passe à José Valim pour cela.

+0

Ne semble pas fonctionner lorsque default_scope a une clause: order et que vous voulez le remplacer. – Zabba

+2

Zabba, c'était exactement mon cas et cela a fonctionné parfaitement pour moi. merci Edgerunner. – taelor

+0

@Zabba, utilisez 'reorder' pour cela – edgerunner

Questions connexes