许多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()