Добавить не буквальный хэш-элемент в магические хэши последнего аргумента Руби? - PullRequest
2 голосов
/ 08 июля 2011

Многие помощники 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, но даже если бы он был.)

Конечно, я могу построить хеш как переменную перед вызовом метода и, при желании, добавить элементы, но ... ick.

Давайте определим, что это надуманные примеры, и предположим, что помощники не допустят :confirm => nil или :id => nil, и что unique_link_id может захотеть опустить идентификатор. Меня больше интересует синтаксис хеша, чем решение проблемы Rails.

Кто-нибудь?

1 Ответ

2 голосов
/ 08 июля 2011

Я думаю, вы должны попробовать что-то вроде следующего:

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 должен вернутьстрока (или ноль, если вы не хотите иметь идентификатор)

Чтобы ответить на ваш вопрос в целом, вам необходимо понять, как rails обрабатывает эти параметры, которые вы передаете в метод (например, помощник).

Большинство помощников рельсов начинаются так:

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

Что вы должны знать о вышесказанном: предполагается, что в качестве параметра передается массив.Все добавляемое вами значение :thing => преобразуется в хеш, который является последним элементом этого массива.Таким образом, 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 ()

...