Pergunta

Eu estou trabalhando em um multi-usuário, multi-conta conta App onde 1 pode ter n usuários. É muito importante que cada usuário só pode informações de acesso de sua conta. Minha abordagem é adicionar um account_id para todos os modelos da DB e que adicionar um filtro em cada controlador para selecionar apenas objetos com o account_id atual. Vou usar o plugin de autorização.

É esta abordagem uma boa idéia?

O que é a melhor maneira de sempre definir o account_id para cada objeto que é criado sem a escrita

object.account = @current_account

em cada ação CRIAR? Talvez um filtro?

Também não tenho certeza sobre a melhor forma de implementar o filtro para as opções selecionadas. Eu preciso de algo como uma condição geral:. Não importa o que aparece mais na instrução SQL, há sempre um "ONDE account_id = XY"

Obrigado por sua ajuda!

Foi útil?

Solução

Este é semelhante a um User.has_many: cenário de e-mails. Você não quer que o usuário veja outros povos e-mails alterando o ID na URL, para que você faça o seguinte:

@emails = current_user.emails

No seu caso, provavelmente você pode fazer algo como isto:

class ApplicationController < ActionController::Base
  def current_account
    @current_account ||= current_user && current_user.account
  end
end

# In an imagined ProjectsController
@projects = current_account.projects
@project = current_account.projects.find(params[:id])

Outras dicas

Eu sei, eu sei, se você acessar sessão de variáveis ??ou variáveis ??de instância em seu modelo você não entender o padrão MVC e "deveria voltar para PHP". Mas ainda assim, isso pode ser muito útil se você tiver - como nós -. Um monte de controladores e ações em que você nem sempre quer escrever @ current_account.object.do_something (não muito DRY)

A solução que encontrei é muito fácil:

Passo 1: Adicione a sua current_account para Thread.current, assim, por exemplo

class ApplicationController < ActionController::Base
  before_filter :get_current_account      

  protected
   def get_current_account
     # somehow get the current account, depends on your approach
     Thread.current[:account] = @account
   end
end

Passo 2: Adicione um método current_account a todos os seus modelos

   #/lib/ar_current_account.rb
   ActiveRecord::Base.class_eval do
     def self.current_account
      Thread.current[:account]
     end
   end

Passo 3: Voilá, em seus modelos que você pode fazer algo como isto:

class MyModel < ActiveRecord::Base

  belongs_to :account

  # Set the default values
  def initialize(params = nil) 
    super
      self.account_id ||= current_account.id
  end

end

Você também pode trabalhar com algo como o retorno de chamada before_validation em active_record e depois fazer com uma validação se a conta é sempre definido.

A mesma abordagem poderia ser usada se você sempre deseja adicionar o current_user para cada objeto criado.

O que você acha?

Para responder à sua segunda pergunta, confira a nova default_scope recurso no Rails 2.3.

Eu entendo que você não quer se preocupar com escopo você conta todos os tempos. Deixa para ser honesto, é uma dor no a **.

Para adicionar uma magia pouco e ter esse escopo feito perfeitamente dar uma olhada no seguinte gem

http://gemcutter.org/gems/account_scopper

Espero que isso ajude,

- Sebastien Grosjean - ZenCocoon

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