Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

333
Vistas
En Ruby, ¿puede decidir regresar o continuar desde un método principal al llamar a un submétodo?

Estoy usando Pundit gem para mis clases de autorización, donde cada acción del controlador se compara con la política del modelo, para ver si el usuario permite la acción.

Estos métodos a veces se vuelven bastante inflados e ilegibles, porque estoy revisando algunas cosas para algunos objetos.

Ahora estoy pensando en refactorizar esos métodos y colocar cada "validación" en su propio método:

Anterior:

 class PostPolicy < ApplicationPolicy def update return true if @user.has_role? :admin return true if @object.owner == user return true if 'some other reason' false end end

Ahora idealmente, quiero refactorizar esto en algo como:

 class PostPolicy < ApplicationPolicy def update allow_if_user_is_admin allow_if_user_owns_record allow_for_some_other_reason false end private def allow_if_user_is_admin # this would go in the parent class, as the logic is the same for other objects return true if @user.has_role? :admin end end

El problema ahora es que el método de update de mane continuará, incluso si el usuario es administrador, ya que no hay retorno. Si incluyo una devolución, entonces los otros métodos nunca serán evaluados. ¿Hay alguna forma en Ruby de hacer una especie de "superretorno", de modo que cuando el usuario sea un administrador, el método de update principal deje de evaluar?

¡Gracias!

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Dado su ejemplo y este comentario: "... ¿no hay una forma nativa de hacer una especie de 'súper retorno' en Ruby? Se siente como una especie de 'aumento' pero luego con un resultado positivo... ¿podría usar eso tal vez? " .

Si bien generalmente hay otras formas de resolver el problema que podrían considerarse "más idiomáticas", Ruby tiene una implementación Kernel#throw y Kernel#catch que puede ser muy útil para controlar el flujo al navegar a través de numerosos y posiblemente métodos y operaciones dispares.

El throw y la catch correspondiente provocarán un cortocircuito en el resultado del bloque que parece ser la sintaxis que está buscando.

Ejemplo MUY Básico:

 class PostPolicy def initialize(n) @n = n end def update catch(:fail) do stop_bad_actor! catch(:success) do allow_if_user_is_admin allow_if_user_owns_record stop_bad_actor!(2) allow_for_some_other_reason false end end end private def allow_if_user_is_admin puts "Is User Admin?" throw(:success, true) if @n == 1 end def allow_if_user_owns_record puts "Is User Owner?" throw(:success,true) if @n == 2 end def allow_for_some_other_reason puts "Is User Special?" throw(:success,true) if @n == 3 end def stop_bad_actor!(m=1) puts "Is a Bad Actor?" throw(:fail, false) if @n == 6 || @n ** m == 64 end end

Salida de ejemplo:

 PostPolicy.new(1).update # Is a Bad Actor? # Is User Admin? #=> true PostPolicy.new(2).update # Is a Bad Actor? # Is User Admin? # Is User Owner? #=> true PostPolicy.new(3).update # Is a Bad Actor? # Is User Admin? # Is User Owner? # Is a Bad Actor? # Is User Special? #=> true PostPolicy.new(4).update # Is a Bad Actor? # Is User Admin? # Is User Owner? # Is a Bad Actor? # Is User Special? #=> false PostPolicy.new(6).update # Is a Bad Actor? #=> false PostPolicy.new(8).update # Is a Bad Actor? # Is User Admin? # Is User Owner? # Is a Bad Actor? #=> false
over 4 years ago · Santiago Trujillo Denunciar

0

Lo que puede hacer es encadenar && operadores.

Tan pronto como uno sea false , Ruby no evaluará los demás (y el método de actualización devolverá false ).

 class PostPolicy < ApplicationPolicy def update allow_if_user_is_admin && allow_if_user_owns_record && allow_for_some_other_reason && end private def allow_if_user_is_admin # this would go in the parent class, as the logic is the same for other objects return true if @user.has_role? :admin end end
over 4 years ago · Santiago Trujillo Denunciar

0

Parece que esto lograría su objetivo y sería más idiomático:

 class PostPolicy < ApplicationPolicy def update user_has_admin_role? || user_owns_object? || some_other_reason? end private def user_has_admin_role? @user.has_role? :admin end def user_owns_object? @object.owner == user end def some_other_reason? 'some other reason' end end
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda