简体   繁体   English

我可以将某种形式的If..End块放入哈希定义中吗?

[英]Can I put some form of If..End blocks inside of a hash definition?

I am creating a web application to integrate with Chargify . 我正在创建一个Web应用程序以与Chargify集成。 I want to return a hash with customer_id set if the user has a customer associated with the account, and customer_attributes if a customer has to be created. 我想回到同一个哈希customer_id组如果用户拥有与账户相关联的客户,并customer_attributes如果客户有被创建。

Is there any way that I could do this with an if..end block inside of the hash definition. 有什么办法可以对哈希定义中的if..end块执行此操作。 For example, I would be wanting to do something like the following (does not work): 例如,我想要做类似以下的事情(不起作用):

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

Use Hash.merge to conditionally merge one set (or another) of key-value pairs: 使用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

尝试过三元运算符?

While you can specify a single value using :key => if bool then val1 else val2 end , there's no way to use an if statement to choose whether to insert a key-value pair while in a literal hash. 虽然可以使用:key => if bool then val1 else val2 end来指定单个 ,但是无法使用if语句来选择是否在文字哈希中插入键值对。

That being said, you could use the oft-overlooked Object#tap method available in Ruby 1.8.7 and Ruby 1.9+ to conditionally insert values into the hash: 话虽如此,您可以使用Ruby 1.8.7和Ruby 1.9+中经常被忽略的Object#tap方法有条件地将值插入哈希:

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"}

The idiomatic way to do this is to take advantage of default nil values in hashes. 惯用的方法是利用哈希中的默认nil值。

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

So, you can set either :customer_id or :customer_attributes , no if statement required, and later test for which one is present. 因此,您可以设置:customer_id:customer_attributes ,无需if语句,然后再测试存在哪个语句。 You might give preference to :customer_id , when you do this. 执行此操作时,您可能会首选:customer_id

unless purchase[:customer_id].nil?
  @customer = Customer.find(purchase[:customer_id])
else
  @customer = Customer.create!(purchase[:customer_attributes])
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM