Почему мне иногда удавалось обойтись без оператора знака знака?

У меня есть рубиновый код из моего проекта Ruby on Rails.

Я форматирую некоторые данные, поэтому я вызываю attributes.extract!, чтобы получить нужные мне поля из моей модели.

Недавно я заметил, что время от времени данные не извлекаются должным образом. Я понял, что мне нужен сплат-оператор. Но это странно, потому что я заметил, что иногда, когда метод вызывается в моем проекте 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, которое случается лишь иногда? В чем дело?


person Gabriel    schedule 22.05.2020    source источник
comment
Какие входные данные вызвали неожиданное поведение?   -  person D. SM    schedule 23.05.2020
comment
Единственным входом в метод всегда является пользовательский объект. Единственное, что, как мне кажется, может вызвать странные проблемы, это то, что я использую before_create для назначения адресных полей. После создания пользователя я затем отправляю его в свой класс обслуживания здесь (я форматирую данные раньше), а затем в классе обслуживания есть еще один метод, в котором он затем отправляется в конечную точку API. Сам метод службы вызывает этот метод форматирования здесь.   -  person Gabriel    schedule 23.05.2020


Ответы (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

Ссылка: нажмите< /а>. Как видите, он создает новый хеш, проходит по keys один за другим и перемещает значение из self в этот новый массив. Таким образом, если вы укажете аргумент Array для этого метода, то key в блоке также будет массивом. Значит, не найдут. Таким образом, это никак не может работать для аргумента массива. Единственная возможность состоит в том, что вместо User::HOME_ADDRESS_FIELDS передается что-то другое.

person kimrgrey    schedule 23.05.2020
comment
Да вот что странно. Ничего, кроме массива, не проходило. Я посмотрю на это немного больше и обновлю свой вопрос всем, что смогу найти. Но спасибо за ссылку на метод извлечения. Помогает узнать, что аргумент массива не должен работать - person Gabriel; 26.05.2020
comment
Хорошо, я думаю, что наконец понял это. На самом деле он не извлекал атрибуты, когда аргумент массива был отправлен. Причина, по которой я думал, что он их извлекает, заключается в том, что я проверял API и увидел, что создается домашний адрес. Но был основной метод, который присваивал почтовый адрес, который я отправлял, был домашним адресом. Это очень много кода для демонстрации других процессов, которые происходили, и его немного сложно объяснить. TLDR, это была проблема, возникающая на клиенте API. отправка массива в .extract! не работает никак - person Gabriel; 26.05.2020