Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

337
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!