De qué clase es self en una vista? Eso quiero saber pues necesito
acceder la clase del controlador actual desde la vista y me pareció que
self era un buen lugar para empezar. He definido variables/métodos de
clase en el controlador para encapsular funcionamiento común. Sé que
podría definir una varible de instance en el controlador y ahí guardar
la clase del controlador, pero me pareció poco elegante y repetitivo.
def una_accion_del_controlador
… @clase_contolador = self.class
…
end
Entonces en la vista traté de obtener la clase de self pero para mi
sorpresa self no es ni Controlador ni Modelo ni nada conocido. Usé el
siguiente código de prueba:
Otra forma que se me ocurre para obtener la clase del controlador actual
es: por medio de params[:controller] que contiene el nombre del
controlador actual, cómo convierto esta String en una clase?
En resumen, lo que necesito acceder la clase del controlador actual
desde la vista.
Gracias de antemano
PS: Para complicarlo aún más la vista en cuestión es el layout y uso el
mismo layout para todos las vistas
Otra forma que se me ocurre para obtener la clase del controlador
actual
En el contexto de una vista se tiene acceso al controlador via el metodo
controller
Pero de todas maneras lo que propones suena sospechoso. Un
controlador es responsable de preparar los datos necesario para
construir la vista, al mas alto nivel posible, pasarselos, y salir
del flujo. Si desde la vista has de volver al controlador (uso
“volver” para enfatizar que la comunicacion sobre el papel va en una
sola direccion) es muy posible que no estes aplicando bien el patron.
Efectivamente como te comenta Xavier si necesitas pasar el controlador
como
variable a la vista, lo más probable es que tengas un error de concepto en
tu
aplicación.Es muy posible que lo que pretendes hacer se consiga o bien añadiendo al
modelo la funcionalidad que necesites (si se trata de la lógica de la
aplicación) o bien sacando el código a un helper(si lo que pretendes es
reutilizar funciones relacionadas con la vista de los datos).
Los métodos de un controlador tienen por misión manipular datos y redirigir
a la vista correspondiente. Volver de la vista al controlador antes de
llegar al usuario es incorrecto, o por lo menos no ortodoxo
class ControladorPrincipal < ActionController::Base
@@se_puede_insertar = true
def self.se_puede_insertar?
@@se_puede_insertar
end
def self.se_puede_insertar=(value)
@@se_puede_insertar = value
end
…
end
class ControladorPrincipalConInsert < ControladorPrincipal
…
end
class ControladorPrincipalSinInsert < ControladorPrincipal
self.se_puede_insertar = false
…
end
El atributo lo guardo en el controlador porque
la relación entre los controladores principales y los modelos
principales es 1:1
la acción new del controlador inserta un nuevo item en el modelo,
entonces en la vista pongo <%= link_to (“Insertar Nuevo”, :action =>
:new) if self.controlador.class.se_puede_insertar %>
En cambio si el atributo estuviera en el modelo, cómo acceso el modelo
del controlador actual desde la vista? Se me ocurre guardar una
referencia del modelo en el controlador y luego accederlo asà desde la
vista: self.controller.model.class.se_puede_insertar, pero creo que es
una versión peor a la anterior: self.controlador.class.se_puede_insertar
Aunque me han dado de que pensar, creen que mi código necesita un
refactorización?
Aunque me han dado de que pensar, creen que mi código necesita un
refactorización?
Por que codificas tanta metainformacion?
Estas cosas suelen ser mas sencillas, uno decide que controladores
quiere, sin acoplarlos al modelo aunque en su organizacion el modelo
puede que influya, y en la vista el programador pone un enlace o no a
crear tal modelo en funcion de si va o no va, como cualquier otro
enlace. Por lo que explicas parece que pones enlaces a crear modelo
en todos los lugares donde podria tener sentido y los condicionas a
esa metainformacion.
Ese diseño en mi opinion es algo rigido y mezcla las tres capas, ya
que establece una relacion entre controladores y modelos principales
que luego percola a las vistas. O es que estas haciendo algun
generador de codigo o algo asi?
No seáis tan talibanes que no hay nada malo en acceder a otra ‘capa’ del
patrón MVC. Por algo desde una vista tenemos disponible la variable
controller. Con controller.class accedes a su clase.
Digamos que mucha programación de esta app se beneficiarÃa de usar un
generador de código especifico para esta app.
Estoy migrando una app que usa una legacy DB a RoR. Mucha de la
funcionalidad que tengo que programar es parecida a un scaffold: (list,
new, edit, show), aunque no tan simple como el scaffold que trae RoR. Me
inspirado un poco en una app de RoR GAL http://gal.railsplayground.com/
y en el gem Streamlined http://streamlined.relevancellc.com/
El código de la app que estoy migrando en gran parte se puede resolver
con un scaffold personalizado, otra parte con programción pura y dura, y
el resto con trucos de Ruby.
Por ejemplo de trucos de Ruby: En la tabla de usuarios hay una columna
donde dice si se tiene o no acceso a un módulo de la app. Vooy a
programar cada módulo como un controlador, entonces hice hash de
controlador => nombre_columna_con_acceso. Entonces con un before filter
valido el acceso
def tiene_acceso
if Usuario.find(:first,
session[:userid]).send(modulos_derechos_hash[params[:controller]]) > 0
# tiene acceso
else
# no tiene acceso
end
end
Mucha funcionalidad de la aplicación se puede resumir en listar,
insertar, editar, borrar; cómo el scaffold que viene con RoR. De hecho
cada módulo principal muestra una lista paginada del modelo - con
filtros y ordenamiento por columna. Para cada fila tenemos las
funcionalidad: show, edit y delete. Y a nivel del layout (que es común
para los controladores principales) la opcion de insertar - si se puede
insertar.
Si creo que es rigido pero esa es mi intención. Quiero que todos los
controladores principales se vean y funcionen iguales, asà a los
usuarios no les costará aprender a usar la app.
La programación pura y dura se dará más adelante, para los casos
especiales, aunque -espero- no sea tan dura.
On Oct 14, 2006, at 8:06 AM, Josh | Vectrice wrote:
No seáis tan talibanes que no hay nada malo en acceder a otra
‘capa’ del patrón MVC. Por algo desde una vista tenemos disponible
la variable controller. Con controller.class accedes a su clase.
Estas cosas no son ni malas ni buenas en terminos absolutos. El
patron MVC no es una verdad platonica!
Ocurre como con los warnings, ante un warning tate, casi nunca me ha
pasado que no tuviera detras un bug. Igualmente desviaciones del
patron (si la intencion es seguirlo, que se asume en Rails) hay que
analizarlas porque es raro que no tengan detras un “error” de diseño.
No es por capricho ni por ganas de tener bonitos diagramas que se
sigue el patron MVC, se sigue porque la experiencia muestra que
permite construir web sites bien organizados. La consecuencia de
mezclar responsabilidades no es desagrado estetico, es que la
implementacion se lia.
Igualmente, cuando alguien pregunta como podria acceder a la sesion
desde un modelo la respuesta unanime es que no tendria que serle
necesario. Lo que el modelo necesite viniendo de la interfaz se lo
tiene que proporcionar el controlador. Es sospechoso que te haga
falta. Eso se señala con voluntad de ayudar, por el bien del codigo,
no por querer hacer seguir ciegamente un patron.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.