Cómo establecer siempre un valor para la cuenta-alcance en Rails?
-
16-09-2019 - |
Pregunta
Estoy trabajando en un multi-usuario, multi-cuenta de la aplicación en la que 1 cuenta puede tener n usuarios. Es muy importante que cada usuario sólo puede acceder a la información de su cuenta. Mi método consiste en añadir una account_id a cada modelo en la base de datos y de añadir un filtro en cada controlador para seleccionar sólo los objetos con el account_id actual. Voy a utilizar el plug-in de autorización.
¿Es este enfoque es una buena idea?
¿Cuál es la mejor manera de establecer siempre la account_id para cada objeto que se crea sin escribir
object.account = @current_account
en cada Crear acción? Tal vez un filtro?
Además, no estoy seguro sobre la mejor manera de aplicar el filtro para seleccionar las opciones. Necesito algo así como una condición general:. No importa lo que aparece en la instrucción SQL, siempre hay un "DONDE account_id = XY"
Gracias por su ayuda!
Solución
Esto es similar a un escenario User.has_many: mensajes de correo electrónico. Usted no quiere que el usuario vea los correos electrónicos de otras personas al cambiar la ID en la URL, por lo que hacer esto:
@emails = current_user.emails
En su caso, es probable que pueda hacer algo como esto:
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])
Otros consejos
Lo sé, lo sé, si accede sesión de variables o variables de instancia en su modelo que no entendía el patrón MVC y "debe volver a PHP". Pero aún así, esto podría ser muy útil si tiene - como nosotros - una gran cantidad de controladores y acciones en las que no siempre se desea escribir @ current_account.object.do_something (no muy seco)
.La solución que he encontrado es muy fácil:
Paso 1: Añadir su current_account a Thread.current, así que por ejemplo
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
Paso 2: Añadir un método current_account a todos sus modelos
#/lib/ar_current_account.rb
ActiveRecord::Base.class_eval do
def self.current_account
Thread.current[:account]
end
end
Paso 3: Voilá, en sus modelos que usted puede hacer algo como esto:
class MyModel < ActiveRecord::Base
belongs_to :account
# Set the default values
def initialize(params = nil)
super
self.account_id ||= current_account.id
end
end
También puede trabajar con algo así como la devolución de llamada before_validation en active_record y luego hacer con una validación de que la cuenta se establece siempre.
El mismo enfoque podría utilizarse si siempre desea agregar el current_user a cada objeto creado.
¿Qué opinas?
Para responder a su segunda pregunta, echa un vistazo a la nueva default_scope
característica en Rails 2.3.
Yo entiendo que usted no quiere que preocuparse acerca de la determinación del alcance su cuenta todos los tiempos. Deja para ser honesto, es un dolor en el un **.
Para añadir un poco de magia y han hecho este alcance la perfección dar un vistazo a la siguiente joya
http://gemcutter.org/gems/account_scopper
Espero que esta ayuda,
- Sebastien Grosjean - ZenCocoon