Tengo un serializador Blueprinter con un campo personalizado (ver captura de pantalla)
field :score_details do |user| user.score_details endy puede ver una advertencia de Rubocop para este bloque y no puedo hacer que desaparezca. Leí el documento de Rubocop: SymbolProc pero sin éxito.
Para explicar en detalle: tengo un modelo de usuario en el que incluyo una inquietud para calcular una puntuación. En esta preocupación tengo 1 método (sin parámetro) que devuelve un número entero simple. Finalmente, uso este método en mi UserSerializer para mostrar mi puntaje en mi interfaz.
Aquí está mi incluir en mi modelo de usuario:
class User < ApplicationRecord include UserScoresConcern endAquí está mi preocupación:
module UserScoresConcern extend ActiveSupport::Concern included do def score_details # this method return 45 for example calculate_user_score_details end end end¿Qué puedo hacer para corregir esta advertencia? ¿Alguien se ha encontrado alguna vez con el mismo problema?
Gracias 🙏
El método de field toma un bloque que será llamado con 2 argumentos el object y las local_options . Ver BlockExtractor#extract
Su problema es que su bloque ignora el hecho de que se proporcionan 2 argumentos y, por lo tanto, Rubocop cree que puede usar Symbold#to_proc (porque cree que solo se envía un único argumento al bloque); sin embargo, si reconoce el segundo argumento, esta advertencia desaparecerá.
field :score_details do |user,_| user.score_details end Aquí reconocemos el segundo argumento usando el carácter de subrayado _ . Esta es una convención estándar para mostrar que no pretendemos usar este argumento.
Otra forma de determinar el método es llamar a su bloque con 2 argumentos es usar una lambda en su lugar
field :score_details, &->(user) {user.score_details} Esto dará como resultado ArgumentError (wrong number of arguments (given 2, expected 1)) porque la lambda solo espera 1 argumento pero se pasan 2 argumentos. Esta es una de las diferencias distintivas entre un Proc estándar y un lambda ( que es un tipo "especial" de Proc ).
El error que experimentó comentado aquí "número incorrecto de argumentos (dado 1, esperado 0)" se puede recrear fácilmente para mostrar lo que realmente está ocurriendo
def example yield "10",2 end example(&:to_s) ArgumentError (wrong number of arguments (given 1, expected 0)) Esto se debe a que, al usar Symbol#to_proc en esta instancia, se evaluará como "10".to_s(2) pero String#to_s no toma ningún argumento como User#score_details , lo que hace que user.score_details(local_options) falle de la misma manera. .
Solo tienes que escribirlo como
field :score_details, &:score_details El motivo es que el operador de prefijo & toma su argumento (en este caso, un símbolo), llama a su método to_proc , se asegura de que sea realmente un proceso y luego lo usa como argumento de bloque.
Para los símbolos, el método to_proc devuelve un proceso de un argumento que es equivalente al método __send__ en el argumento. Es decir:
# these are functionally equivalent: :my_symbol.to_proc ->(arg) { arg.__send__(:my_symbol) } ->(arg) { arg.my_symbol } La diferencia es que Symbol#to_proc podría decirse que está más optimizado.
Me las arreglo para que funcione pero sin un campo personalizado.
Agrego mi método directamente en mi lista de campos así y funciona:
fields :email, :score_details