Могу ли я поместить некоторую форму блоков If..End в определение хеша? - PullRequest
1 голос
/ 06 апреля 2010

Я создаю веб-приложение для интеграции с Chargify . Я хочу вернуть хэш с установленным customer_id, если у пользователя есть клиент, связанный с учетной записью, и customer_attributes, если необходимо создать клиента.

Есть ли способ сделать это с помощью блока if..end внутри определения хеша. Например, я хотел бы сделать что-то вроде следующего (не работает):

def subscription_params(product_id)
  {
    :product_id => product_id,
    if customer_id.nil?
      :customer_attributes => customer_params,
    else
      :customer_id => customer_id,
    end
    :credit_card_attributes => credit_card_params
  }
end

Ответы [ 4 ]

3 голосов
/ 06 апреля 2010

Используйте Hash.merge для условного объединения одного набора (или другого) пар ключ-значение:

def subscription_params(product_id)
  {
    :product_id => product_id,
    :credit_card_attributes => credit_card_params
  }.merge(customer_id.nil? ?
    { :customer_attributes => customer_params } :
    { :customer_id => customer_id }
  )
end
2 голосов
/ 06 апреля 2010

пробовал троичный оператор?

1 голос
/ 06 апреля 2010

Идиоматический способ сделать это состоит в том, чтобы использовать значения по умолчанию nil в хешах.

> myHash = {:x => :y}  # => {:x=>:y}
> myHash[:d]           # => nil

Таким образом, вы можете установить либо :customer_id, либо :customer_attributes, no, если требуется оператор, и более поздний тест, для которого он присутствует. При этом вы можете отдать предпочтение :customer_id.

unless purchase[:customer_id].nil?
  @customer = Customer.find(purchase[:customer_id])
else
  @customer = Customer.create!(purchase[:customer_attributes])
end
1 голос
/ 06 апреля 2010

Несмотря на то, что вы можете указать одно значение , используя :key => if bool then val1 else val2 end, невозможно использовать оператор if для выбора, вставлять ли пару ключ-значение в литеральный хеш.

При этом вы можете использовать часто пропускаемый метод Object#tap, доступный в Ruby 1.8.7 и Ruby 1.9+, чтобы условно вставить значения в хеш:

irb(main):006:0> { :a => "A"}.tap { |h| if true then h[:b] = "B" end }.tap { |h| if false then h[:c] = "D" end }
=> {:b=>"B", :a=>"A"}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...