Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

331
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda