【问题标题】:Rubocop warning SymbolProc in blueprinter serializer custom field in RailsRails 中蓝图序列化程序自定义字段中的 Rubocop 警告 SymbolProc
【发布时间】:2021-11-05 07:14:46
【问题描述】:

我有一个带有自定义字段的蓝图序列化程序(见屏幕截图)

field :score_details do |user|
  user.score_details
end

你可以看到这个块的 Rubocop 警告,我不能让它消失。我阅读了 Rubocop 文档:SymbolProc 但没有成功..

详细解释:我有一个用户模型,其中包含一个关注点以计算分数。在这个问题上,我有 1 个方法(没有参数),它返回一个简单的整数。 最后,我在UserSerializer 中使用了这个方法,以便将我的分数呈现到我的前端。

这是我在我的用户模型中包含的内容:

class User < ApplicationRecord
  include UserScoresConcern
end

这是我的担忧:

module UserScoresConcern
  extend ActiveSupport::Concern

  included do
    def score_details
      # this method return 45 for example
      calculate_user_score_details
    end
  end
end

我可以做些什么来解决这个警告?有没有人遇到过同样的问题?

谢谢????

【问题讨论】:

  • 字段:score_details (&:score_details)
  • 请以文本形式包含代码,而不是您的编辑器/终端等的屏幕截图。它们不可索引、不可搜索或可访问。
  • @Deepak Mahakale field :score_details (&amp;:score_details) 不起作用????

标签: ruby-on-rails ruby serialization rubocop


【解决方案1】:

field 方法采用一个块,该块将使用objectlocal_options 两个参数调用。 See BlockExtractor#extract

您的问题是您的块忽略了提供 2 个参数的事实,因此 Rubocop 认为您可以使用 Symbold#to_proc(因为它认为只有一个参数发送到块);但是,如果您承认第二个参数,则此警告将消失。

field :score_details do |user,_| 
  user.score_details
end

这里我们使用下划线字符_ 来确认第二个参数。这是一个标准约定,表明我们不打算使用此参数。

确定方法的另一种方法是使用 2 个参数调用您的块,而是使用 lambda

field :score_details, &->(user) {user.score_details}

这将导致ArgumentError (wrong number of arguments (given 2, expected 1)),因为 lambda 只需要 1 个参数,但有 2 个参数被传入。这是标准 Proc 和 lambda(这是一个“特殊” Proc 的类型)。

您遇到的错误Commented Here“参数数量错误(给定 1,预期为 0)” 可以轻松重新创建以显示实际发生的情况

def example
  yield "10",2
end 

example(&:to_s)
ArgumentError (wrong number of arguments (given 1, expected 0))

这是因为在这种情况下使用 Symbol#to_proc 时,它将评估为 "10".to_s(2)String#to_s 不会像 User#score_details 那样接受任何参数,从而导致 user.score_details(local_options) 以同样的方式失败。

【讨论】:

  • 不错的收获。我不知道额外的参数被转发给方法。我以后一定会好好利用它的:)
  • @fralps 请将此标记为正确答案
  • @rewritten 是的,它是那些未被充分利用的隐藏功能之一,例如 enum_for
【解决方案2】:

你只需要把它写成

field :score_details, &:score_details

原因是&amp;前缀运算符接受它的参数(在本例中是一个符号),调用它的to_proc方法,确保它实际上是一个proc,然后将它用作块参数。

对于符号,to_proc 方法返回一个单参数 proc,它等效于参数上的 __send__ 方法。那就是:

# these are functionally equivalent:
:my_symbol.to_proc
->(arg) { arg.__send__(:my_symbol) }
->(arg) { arg.my_symbol }

不同之处在于Symbol#to_proc 可以说更加优化。

【讨论】:

  • 是的,警告消失了,但我有一个 500 wrong number of arguments (given 1, expected 0)
  • @fralps Symbol#to_proc 返回的过程需要一个参数,因此在其他地方引发异常。你能分享回溯(至少是它的顶部)吗?
  • ` app/serializers/user_serializer.rb:13:in block (2 levels) in &lt;class:UserSerializer&gt;'
  • 那么user.score_details 本身很可能需要一个参数。
  • 您的最后一节“这些在功能上是等效的:” 不正确。例如a = :to_i.to_proc; b = -&gt;(arg) { arg.__send__(:to_i)} 然后a.("10", 2) #=&gt; 2b.("10",2) #=&gt; ArgumentErrorSymbol#to_proc 的功能等价于-&gt;(arg,*rest) { arg.public_send(:my_symbol,*rest)}
【解决方案3】:

我设法让它工作,但没有自定义字段。

我像这样直接将我的方法添加到我的字段列表中并且它有效:

fields  :email,
        :score_details

【讨论】:

    猜你喜欢
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 2015-01-27
    • 2019-01-17
    • 2018-10-06
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    相关资源
    最近更新 更多