Estoy trabajando en una aplicación de Rails (actualmente 2.3.4) que hace uso de subdominios para aislar sitios de cuenta independientes. Para que quede claro, lo que quiero decir es que foo.mysite.com debe mostrar el contenido de la cuenta foo y bar.mysite.com debe mostrar el contenido de la barra.Rieles: ¿práctica recomendada para las consultas de alcance basadas en el subdominio?
¿Cuál es la mejor manera de asegurarse de que todas las consultas de modelo tengan el alcance del subdominio actual?
Por ejemplo, uno de mis reguladores se ve algo como:
@page = @global_organization.pages.find_by_id(params[:id])
(Nota @global_organization
se encuentra en el application_controller través subdominio-fu.) Cuando lo que preferiría es algo así como:
@page = Page.find_by_id(params[:id])
donde los hallazgos del modelo de página se asignan automáticamente a la organización correcta. He intentado usar la directiva default_scope así: (en el modelo de página)
class Page < ActiveRecord::Base
default_scope :conditions => "organization_id = #{Thread.current[:organization]}"
# yadda yadda
end
(Una vez más, sólo para observar, el mismo establece application_controller Thread.current [: organización] a Identificación de la organización para el acceso global. El problema con este enfoque es que el alcance predeterminado se establece en la primera solicitud y nunca cambia en solicitudes posteriores a diferentes subdominios.
tres soluciones aparentes hasta el momento:
1 Use VHosts separadas para cada subdominio y sólo ejecutar diferentes instancias de la aplicación por subdominio (usando mod_rails). Este enfoque no es escalable para esta aplicación.
2 Utilice el enfoque del controlador original anterior. Desafortunadamente, hay un buen número de modelos en la aplicación y muchos de los modelos se eliminan de la organización, por lo que esta notación se vuelve cada vez más engorrosa. Lo que es peor es que esto requiere activamente que los desarrolladores recuerden y apliquen la limitación o arriesguen un problema de seguridad significativo.
3 Utilice a before_filter para restablecer el alcance predeterminado de los modelos en cada solicitud. No estoy seguro sobre el rendimiento alcanzado aquí o cuál es la mejor manera de seleccionar qué modelos actualizar por reqeust.
¿Pensamientos? ¿Alguna otra solución que me falta? Esto parece ser un problema bastante común que tiene que haber una mejor práctica. Toda la información apreciada, ¡gracias!
Gracias por el aporte! ¿Has probado ese código en la práctica? Acabo de probarlo en la aplicación y, aunque puedo confirmar que efectivamente se está evaluando la lambda en cada búsqueda, el valor predeterminado_scope no aplica los valores devueltos. Mirando el resultado SQL, las condiciones parecen simplemente ignoradas. Por muchas otras razones, aún no he podido arrancar mi depurador, pero voy a hacer un pico tan pronto como vuelva a funcionar. ¿Pensamientos sobre por qué podría no funcionar? – qfinder
Honestamente, no tengo idea de cómo el servidor interno usa subprocesos, por lo que asumí 'Thread.current [: organization]' trabajado en el modelo. Pero no sé si eso explicaría por qué se ignoran las condiciones. Como esencialmente está definiendo el alcance predeterminado para buscar organazation_id = nil. – EmFi
Tras una investigación adicional, parece que esto no funciona todavía. Hay un parche, pero YMMV: https://rails.lighthouseapp.com/projects/8994/tickets/1812-default_scope-cant-take-procs – EmFi