Question

J'ai quelques modèles qui nécessitent des conditions de recherche personnalisées. Par exemple, si j’ai un modèle Contact, chaque fois que Contact.find est appelé, je souhaite limiter les contacts renvoyés qui appartiennent uniquement au compte utilisé.

J'ai trouvé ceci via Google (que j'ai un peu personnalisé):

def self.find(*args)
  with_scope(:find => { :conditions =>  "account_id = #{$account.id}" }) do
    super(*args)
  end
end

Cela fonctionne très bien, sauf dans quelques cas où account_id est ambigu. Je l'ai donc adapté à:

def self.find(*args)
  with_scope(:find => { :conditions =>  "#{self.to_s.downcase.pluralize}.account_id = #{$account.id}" }) do
    super(*args)
  end
end

Cela fonctionne également très bien, cependant, je veux que ce soit sec. Maintenant, j'ai quelques modèles différents pour lesquels je souhaite utiliser ce type de fonction. Quelle est la meilleure façon de faire cela?

Lorsque vous répondez, veuillez inclure le code pour aider notre esprit à comprendre la métaprogrammation Ruby-fu.

(J'utilise Rails v2.1)

Était-ce utile?

La solution

Vous ne nous dites pas quelle version de rails vous utilisez [edit - c’est sur les rails 2.1, les conseils suivants sont donc pleinement opérationnels], mais je vous recommande d’utiliser le formulaire suivant au lieu de surcharger, trouvez vous-même:

account.contacts.find(...) 

Ceci encapsulera automatiquement la recherche dans une étendue où la clause user est incluse (puisque vous avez le account_id, je suppose que vous avez le compte quelque part)

Je vous suggère de consulter les ressources suivantes sur les portées

Autres conseils

Le conseil de Jean est judicieux. En supposant que vos modèles ressemblent à ceci:

class Contact < ActiveRecord::Base
  belongs_to :account
end

class Account < ActiveRecord::Base
  has_many :contacts
end

Vous devriez utiliser l'association contacts du compte actuel pour vous assurer que vous n'obtenez que des enregistrements Contact affectés à ce compte, comme suit:

@account.contacts

Si vous souhaitez ajouter d'autres conditions à votre requête de contacts, vous pouvez les spécifier à l'aide de find:

@account.contacts.find(:conditions => { :activated => true })

Et si vous recherchez constamment des utilisateurs activés, vous pouvez le refactoriser dans une étendue nommée:

class Contact < ActiveRecord::Base
  belongs_to :account
  named_scope :activated, :conditions => { :activated => true }
end

Ce que vous utiliseriez ensuite comme ceci:

@account.contacts.activated

pour donner une réponse spécifique à votre problème, je suggèrerais de transférer la méthode susmentionnée dans un module à inclure dans les modèles en question; donc vous auriez

class Contact
  include NarrowFind
  ...
end

PS. Méfiez-vous des échappements sql de account_id, vous devez probablement utiliser la syntaxe : conditions = > [" .... =? ", $ account_id] .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top