62 votes

Comment utiliser non relié sur les relations associées dans Rails3?

J'ai un défaut portée sur les produits en raison de la sécurité de l'information à des contraintes.

class Product < ActiveRecord::Base
  has_many :photos

  default_scope where('visible = 1')
end

Dans mon associé modèle Photo, cependant, j'ai aussi de trouver des produits qui ne doit pas être visible.

class Photo < ActiveRecord::Base
  belongs_to :product
end

my_photo.product

Dans d'autres cas, je peux l'utiliser non délimité , afin de contourner le default_scope, par exemple, en Product.unscoped.find_by_title('abc'). Cependant:

Comment faire pour supprimer le champ d'application lors de l'utilisation d'associations d'un enregistrement?

my_photo.unscoped.product n'a pas de sens en tant que my_photo ne dispose pas d'une méthode appelée unscoped. N' my_photo.product.unscoped sens comme my_photo.product peut déjà être nul.

62voto

crispy Points 2599

Oh. J'ai trompé moi-même. Pensé que le suivant ne marche pas... mais il n':

Product.unscoped do
  my_photo.product
end

Notez que vous devez appeler non délimités sur le modèle avec l' default_scope qui devrait être contournée.

Aussi, l'héritage doit être respecté. Si vous avez class InsuranceProduct < Productet class FinancialProduct < Product et default_scope en Product, tous les deux combinaisons de travail:

InsuranceProduct.unscoped do
  my_record.insurance_products
end

FinancialProduct.unscoped do
  my_record.financial_products
end

Product.unscoped do
  my_record.products
end

Cependant, la suivante ne fonctionnera pas bien que le champ d'application est défini en Product:

Product.unscoped do
  my_record.financial_products
end

Je suppose que c'est une autre bizarrerie de la STI dans Ruby / Rails.

50voto

cowboycoded Points 7505

Une autre option consiste à redéfinir la méthode d'accesseur en lecture et à supprimer unscope super:

 class Photo < ActiveRecord::Base
  belongs_to :product

  def product
    Product.unscoped{ super }
  end
end
 

Je me suis retrouvé dans la même situation où j'avais un modèle associé qui devait être non délimité, mais dans presque tous les autres cas, il avait besoin de la portée par défaut. Cela devrait vous éviter les appels supplémentaires non résolus si vous utilisez l'assistant de sélection d'association à plusieurs endroits.

24voto

markets Points 1400

Je suis probablement un peu en retard à la fête, mais il y a quelque temps, je me suis retrouvé dans la même situation et j'ai écrit un bijou pour le faire facilement: unscoped_associations .

Usage:

 belongs_to :user, unscoped: true
 

Soutien:

  • appartient à
  • en a un
  • a beaucoup

Les associations polymorphes sont également supportées.

1voto

no-dashes Points 16

Ce n'est pas le sujet principal mais sur votre problème avec ActiveRecord#devient: Nous (espérons-le) il fixe avec un initialiseur

 classe ActiveRecord::Base

 def becomes_with_association_cache(klass)
 est devenu = becomes_without_association_cache(klass)
 est devenu.instance_variable_set("@association_cache", @association_cache)
est devenu
fin
 alias_method_chain :devient :association_cache

fin

https://gist.github.com/2478161

0voto

noodl Points 8992

Nouvelle réponse

Cette question devrait vous aider à comprendre comment contourner la clause where par défaut pour votre association.

Il vaut la peine de répéter cependant que si vous devez régulièrement éviter une portée, elle devrait probablement être un défaut. Créez une étendue visible autre que celle par défaut et utilisez-la explicitement dans vos associations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X