Некоторые творческие исправления хеша ошибок Rails позволят вам достичь вашей цели. Создайте инициализатор в config/initalizers
, позвольте назвать его errors_hash_patch.rb
и поместите в него следующее:
ActiveModel::Errors.class_eval do
def [](attribute)
attribute = attribute.to_sym
dotted_attribute = attribute.to_s.gsub("_", ".").to_sym
attribute_result = get(attribute)
dotted_attribute_result = get(dotted_attribute)
if attribute_result
attribute_result
elsif dotted_attribute_result
dotted_attribute_result
else
set(attribute, [])
end
end
end
Все, что вы здесь делаете, это просто переопределяете метод доступа []
, чтобы попробовать немного сложнее. Более конкретно, если ключ, который вы ищете, имеет подчеркивание, он попытается найти его как есть, но если он не сможет ничего найти, он также заменит все подчеркивания точками и попытается найти это тоже. В остальном поведение такое же, как и у обычного []
метода. Например, допустим, у вас есть хэш ошибок, подобный хешу из вашего примера:
errors = {:"account.firstname"=>["is too short", "can not be blank"], :"account.lastname"=>["is too short", "can not be blank"], :account=>["is invalid"]}
Вот некоторые способы, которыми вы можете получить к нему доступ, и результаты, которые возвращаются:
errors[:account] => ["is invalid"]
errors[:"account.lastname"] => ["is too short", "can not be blank"]
errors[:account_lastname] => ["is too short", "can not be blank"]
errors[:blah] => []
Мы не изменяем способ хранения ключей в хэше ошибок, поэтому мы не будем случайно нарушать библиотеки и поведение, которые могут зависеть от формата хэша. Все, что мы делаем, - это немного разумнее с точки зрения доступа к данным в хэше. Конечно, если вы действительно хотите изменить данные в хэше, шаблон будет таким же, вам просто нужно переопределить метод []=
, и каждый раз, когда rails пытается сохранить ключи с точками в них, просто измените точки на подчеркивает.
Что касается вашего второго вопроса, хотя я и показал вам, как делать то, что вы просите, в общем, лучше всего попытаться выполнить то, как рельсы пытаются делать вещи, а не пытаться согнуть рельсы к вашему. будут. В вашем случае, если вы хотите отображать сообщения об ошибках через javascript, возможно, ваш javascript будет иметь доступ к хешу данных об ошибках, так почему бы не настроить эти данные с помощью javascript в нужном вам формате. В качестве альтернативы вы можете клонировать данные об ошибках внутри контроллера и настроить их там (до того, как ваш javascript когда-либо получит к ним доступ). Трудно дать совет, не зная больше о вашей ситуации (как вы пишете свои формы, что именно делает ваша проверка JS и т. Д.), Но это общие рекомендации.