ruby on rails - rails - ¿Reemplazo declarativo de programación ruby para if/then/else/RETURN/end?
ruby on rails que es (5)
Como otros han dicho, un before_filter parece ser la herramienta correcta aquí. Pero abordaré el patrón real sobre el que preguntaba.
Lamentablemente, un método no puede hacer que regrese su método de llamada. Las dos coincidencias más cercanas al patrón que está buscando:
Un bloque:
def require_rights(rights)
if session[rights]
yield
else
flash[:notice] = "You don''t have the rights to do #{:action}."
redirect_to :action=>:index
end
end
Entonces con eso harías:
def action_which_requires_rights
require_rights :admin do
#do whatever here
end
end
O un valor de retorno:
def require_rights(rights)
return true if session[rights]
flash[:notice] = "You don''t have the rights to do #{:action}."
redirect_to :action=>:index
false
end
Entonces con eso harías:
def action_which_requires_rights
require_rights :admin or return
#do whatever here
end
Me gusta más el bloque porque encaja con métodos similares, y hacer que el que llama haga or return
parece antinatural.
Tengo esto apareciendo en mis controladores:
if not session[:admin]
flash[:notice] = "You don''t have the rights to do #{:action}."
redirect_to :action=>:index
return
end
Y su hermano:
if not session[:user] and not session[:admin]
flash[:notice] = "You don''t have the rights to do #{:action}."
redirect_to :action=>:index
return
end
Me gustaría reducir todo esto a una sola línea declarativa cuando quiero usarlo en un método:
def action_which_requires_rights
require_rights :admin
#or:
#:require_rights :user_or_admin
end
Claramente, si require_rights falla, no quiero que se ejecute el resto del método. Juraría que había una manera de hacer esto, pero no puedo encontrar dónde lo leí. ¿Me estoy imaginando esto?
En primer lugar, puede hacer: a unless session[:admin]
lugar de if not ...
Entonces puede tener un filtro anterior que llame a su método, este método haría su redireccionamiento a "url" y lo devolverá.
Tengo una pregunta, espero que no solo almacene el ID del administrador en una sesión como su único medio de autenticación, tener un atributo en su modelo de usuario y consultar que podría ser una apuesta más segura.
Mira before_filter. Pueden detener la ejecución y pueden limitarse a ciertas acciones.
No mostraría una acción al usuario si el usuario no tiene permiso para ejecutar esta acción (usaría ayudantes para lograr eso)
En los controladores, como se menciona en otras respuestas, el mejor enfoque es utilizar antes los filtros para controlar los derechos de acceso.
También sugeriría utilizar un plugin de autenticación relajante para administrar roles de usuario.
Podría intentar algo que arroje una excepción.
def action_for_admins
require_rights :admin
end
begin
action_for_admins
rescue
<%= You don''t have the rights to do that %>
end
A continuación, require_rights debería verse algo así
def require_rights(*rights)
rights.each do |right|
raise "Missing right #{right.to_s}" if not user.has_right?(right)
end
end
Tenga en cuenta que soy un principiante en Ruby o Rails, por lo que puede no ser el camino .