将非文字哈希元素添加到 Ruby 的最后一个参数魔术哈希中?



许多Rails帮助程序使用惯用的选项散列作为最后一个参数;Ruby会自动将额外的方法参数插入该散列中。我经常发现自己想要有条件地插入元素,或者编写提供该元素的帮助程序。伪ruby中的两个例子:

link_to "Example 1", "http://www.example.com", needs_confirmation? ? :confirm => "Are you sure?" : nil    # syntax error; nil can't be a hash element

link_to "Example 2", "http://www.example.com", unique_link_id
# I don't want to return a hash; I want to return an element of a hash
def unique_link_id
  :id => "our_link_#{user.id}"    # Syntax error
  {:id => "our_link_#{user.id}"}  # valid, but returns a hash that ends up being an element of the options hash
  {:id => "our_link_#{user.id}"}.flatten_into_my_parent_hash  # What's in my brain
end

是否有一些优雅的方法来做到这一点?显然,我不能控制Rails帮助程序,所以我不能强迫它们平面化哈希。(呃,不是说有Hash#flatten方法,但即使有。)

当然,我可以在方法调用之前将散列构建为变量,并可选地添加元素,但是……我吐!

让我们假设这些是人为的例子,并假设助手不允许:confirm => nil:id => nil,并且unique_link_id可能想要离开ID。比起解决Rails问题,我更感兴趣的是哈希语法。

有人知道吗?

我认为你应该尝试一下:

link_to "Example 1", "http://www.example.com", :confirm => needs_confirmation? ? "Are you sure?" : nil

对于第二种情况,你可以用类似的方式说:

link_to "Example 2", "http://www.example.com", :id=>unique_link_id

注意:unique_link_id应该返回一个字符串(或者nil,如果你不想有一个id)

一般来说,要回答您的问题,您需要了解rails如何处理您在方法(例如helper)中传递的这些参数。

大多数rails帮助程序是这样开始的:

def a_helper(*args)
  options = args.extract_options!
  ...
end

你应该知道的是:假设一个Array作为参数传入。您添加的所有:something=>值都被转换为哈希值,这是该数组的最后一个元素。因此,extract_options!将正常参数与哈希选项分开。所以为了你想要的工作,所有的选项应该在一个散列结束。

要使一个很长的故事排序,这里有一个你应该做的例子:

 link_to "Example 1", "http://www.example.com",{:confirm=>"Are you sure?"}.merge(unique_link_id)

在这种情况下,unique_link_id返回一个散列并与其他选项合并。如果unique_link_id返回一个空散列({}),则不会添加任何选项,并且每个人都很高兴:)

如果你的选项太复杂,我建议你在调用你想要的助手(或方法)之前创建一个选项变量。在将options作为最后一个参数传递给方法之前,它应该是一个与其他哈希合并多次的哈希。

提示:非常有用的散列函数是hash.merge(), hash.merge!()和hash.reverse_merge()

最新更新