Pergunta

Eu tenho alguns modelos que precisam ter condições de localização personalizadas colocadas neles.Por exemplo, se eu tiver um modelo Contact, toda vez que Contact.find for chamado, quero restringir os contatos retornados que pertencem apenas à conta em uso.

Encontrei isso no Google (que personalizei um pouco):

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

Isso funciona muito bem, exceto em algumas ocasiões em que account_id é ambíguo, então adaptei-o para:

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

Isso também funciona muito bem, no entanto, quero que esteja SECO.Agora tenho alguns modelos diferentes que desejo que esse tipo de função seja usado.Qual é a melhor maneira de fazer isso?

Ao responder, inclua o código para ajudar nossas mentes a compreender a metaprogramação Ruby-fu.

(Estou usando Rails v2.1)

Foi útil?

Solução

Você não nos diz qual versão do Rails você está usando [editar - está no Rails 2.1, portanto, o conselho a seguir está totalmente operacional], mas eu recomendo que você use o seguinte formulário em vez de sobrecarregar o find:

account.contacts.find(...) 

isso envolverá automaticamente a descoberta em um escopo onde a cláusula do usuário está incluída (já que você tem o account_id, presumo que você tenha a conta em algum lugar próximo)

Sugiro que você verifique os seguintes recursos sobre escopos

Outras dicas

O conselho de Jean é válido.Supondo que seus modelos sejam assim:

class Contact < ActiveRecord::Base
  belongs_to :account
end

class Account < ActiveRecord::Base
  has_many :contacts
end

Você deveria estar usando o contacts associação da conta corrente para garantir que você só receberá Contact registros com escopo para essa conta, assim:

@account.contacts

Se desejar adicionar mais condições à sua consulta de contatos, você pode especificá-las usando find:

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

E se você estiver constantemente consultando usuários ativados, poderá refatorá-lo em um escopo nomeado:

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

Que você usaria assim:

@account.contacts.activated

para dar uma resposta específica ao seu problema, sugiro mover o método mencionado acima para um módulo a ser incluído pelos modelos em questão;então você teria

class Contact
  include NarrowFind
  ...
end

PS.cuidado com o escape sql do account_id, você provavelmente deve usar o :conditions=>[".... =?", $account_id] sintaxe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top