【问题标题】:Why was I able to get away with not using a splat operator sometimes为什么有时我能侥幸不使用 splat 运算符
【发布时间】:2020-09-09 20:40:51
【问题描述】:

我的 Ruby on Rails 项目中有一些 Ruby 代码。

我正在格式化一些数据,所以我打电话给attributes.extract! 以从我的模型中获取我需要的字段。

我最近注意到,有时无法按预期提取数据。我意识到我需要一个 splat 运算符。但这很奇怪,因为我确实注意到有时在我的 Rails 项目中调用该方法时,它有时会在不使用 splat 运算符的情况下提取数据。但是当我从我的 Rails 控制台运行代码时,它永远不会提取数据,除非我添加 splat 运算符。

这是有问题的代码

  # in a service file, let's call it service.rb
  def self.format_user_home_address_data(user)
    # This doesn't work in the console but sometimes works when run in my Rails project
    home_address_data = user.attributes.extract!(User::HOME_ADDRESS_FIELDS)

    home_address_data[:address_type] = "home"
    home_address_data
  end

  # at the end this method will sometimes return { address_type: "home" } or 
  # sometimes it'll actually return the extracted attributes as expected

HOME_ADDRESS_FIELDS 只是一个数组,其值为["address_line_1", "city", "state", "zip"]

无论如何,我知道要让它正常运行,我需要这样做

    home_address_data = user.attributes.extract!(*User::HOME_ADDRESS_FIELDS)

但是有谁知道为什么我这么长时间没有添加 splat 运算符就可以逃脱?是否有一些 Ruby on Rails 魔法只是偶尔发生?有什么关系?

【问题讨论】:

  • 产生令人惊讶的行为的输入是什么?
  • 该方法的唯一输入始终是用户对象。我认为可能会导致奇怪问题的唯一一件事是我使用before_create 来分配地址字段。创建用户后,我将其发送到我的服务类(我之前格式化数据),然后在服务类中有另一种方法,然后将其发送到 API 端点。服务方法本身就是在这里调用这个格式化方法。

标签: arrays ruby-on-rails ruby splat


【解决方案1】:

好吧,让我们检查一下。最后attributes.extract!背后没有任何魔力。这是 Rails 源代码中此方法的实际实现:

def extract!(*keys)
  keys.each_with_object(self.class.new) { |key, result| 
    result[key] = delete(key) if has_key?(key) 
  }
end

链接:click。如您所见,它创建了新的散列,逐一遍历keys,并将值从self 移动到这个新数组。所以,如果你给这个方法一个数组参数,那么块中的key 也将是一个数组。所以,不会被发现。所以,它不可能适用于数组参数。唯一的一种可能性是传递了其他东西而不是 User::HOME_ADDRESS_FIELDS

【讨论】:

  • 是的,这很奇怪。除了数组之外,没有任何东西可以通过。我会进一步研究它,并用我能找到的任何东西来更新我的问题。但感谢提取方法的链接。有助于了解 Array arg 不应该工作
  • 好吧,我想我终于想通了。发送数组参数时,它实际上并没有提取属性。我认为它正在提取它们的原因是我正在检查 API 并看到正在创建家庭地址。但是有一种底层方法将我发送的邮寄地址指定为家庭地址。对于正在发生的其他进程,要显示很多代码,而且有点难以解释。 TLDR 这是 API 客户端上发生的问题。在 .extract 中发送一个数组!没有任何作用
猜你喜欢
  • 2013-08-19
  • 1970-01-01
  • 2020-10-22
  • 1970-01-01
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多