Como sempre definir um valor para conta-scope em Rails?
-
16-09-2019 - |
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 ??p>
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!
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