У меня есть форма рельсов с полем datetime_select. Когда я пытаюсь отправить форму, я получаю следующее исключение:
ActiveRecord::MultiparameterAssignmentErrors in WidgetsController#update
1 error(s) on assignment of multiparameter attributes
Если это ошибка проверки, почему я не вижу ошибки на странице?
Это в Rails 2.0.2





Оказывается, что rails использует так называемое многопараметрическое назначение для передачи даты и времени небольшими частями, которые собираются повторно, когда вы назначаете параметры экземпляру модели.
Моя проблема заключалась в том, что я использовал поле формы datetime_select для поля модели даты. По-видимому, он задыхается, когда магия с несколькими параметрами пытается установить время для объекта Date.
Решением было использовать поле формы date_select, а не datetime_select.
ActiveRecord выдает исключение MultiparameterAssignmentErrors, когда вы пытаетесь установить недопустимую дату для атрибута модели.
Попробуйте выбрать дату 31 ноября из раскрывающегося списка date_select или datetime_select, и вы получите эту ошибку.
Эта ошибка также может возникать с webrat / cucumber при заполнении данных формы с помощью таблицы.
например, это не работает:
When I fill in the following:
| report_from_1i | 2010 |
| report_from_2i | January |
| report_from_3i | 1 |
| report_to_1i | 2010 |
| report_to_2i | February |
| report_to_3i | 1 |
но это делает:
When I fill in the following:
| report_from_1i | 2010 |
| report_from_2i | 1 |
| report_from_3i | 1 |
| report_to_1i | 2010 |
| report_to_2i | 2 |
| report_to_3i | 1 |
Супер взлом, но мне нужно было сразу решить эту проблему для клиентского проекта. Это все еще ошибка Rails 2.3.5.
Используя date_select или datetime_select, если вы добавите это в свою модель в методе initialize, вы можете предварительно проанализировать переданные сериализованные атрибуты формы, чтобы заставить его работать:
def initialize(attributes = {})
date_hack(attributes, "deliver_date")
super(attributes)
end
def date_hack(attributes, property)
keys, values = [], []
attributes.each_key {|k| keys << k if k =~ /#{property}/ }.sort
keys.each { |k| values << attributes[k]; attributes.delete(k); }
attributes[property] = values.join("-")
end
Я использую это с вложенной полиморфной моделью. Вот вопрос, который у меня был, показывая модели, которые я использую. Поэтому мне нужен accepts_nested_attributes_for с датой и временем.
Вот ввод и вывод с помощью консоли:
e = Event.last
=> #<Event id: 1052158304 ...>
e.model_surveys
=> []
e.model_surveys_attributes = [{"survey_id"=>"864743981", "deliver_date(1i)"=>"2010", "deliver_date(2i)"=>"2", "deliver_date(3i)"=>"11"}]
PRE ATTRIBUTES: {"survey_id"=>"864743981", "deliver_date(1i)"=>"2010", "deliver_date(2i)"=>"2", "deliver_date(3i)"=>"11"}
# run date_hack
POST ATTRIBUTES: {"survey_id"=>"864743981", "deliver_date"=>"2010-2-11"}
e.model_surveys
=> [#<ModelSurvey id: 121, ..., deliver_date: "2010-02-11 05:00:00">]
>> e.model_surveys.last.deliver_date.class
=> ActiveSupport::TimeWithZone
В противном случае он был либо нулевым, либо выдала ошибку:
1 error(s) on assignment of multiparameter attributes
Надеюсь, это поможет, Копье
К сожалению, эта проблема все еще существует в Rails 3. Кто-нибудь знает лучшее решение? В настоящее время у меня есть что-то вроде этого в контроллере: # Поймать исключение из AR :: Base rescue ActiveRecord :: MultiparameterAssignmentErrors => e # Итерировать исключения и удалить недопустимые компоненты поля из входных данных e.errors.each {| err | params [: событие] .delete_if {| ключ, значение | key = ~ /^#{err.attribute}/}} # Повторно создать модель с удаленными неверными полями ввода @event = Event.new (params [: event])
В моем случае плагин ActiveRecord am / pm вызвал ошибку из-за неправильного alias_method_chain, что привело к исключению StackLevelTooDeep.
Плагин был включен плагином unobtrusive_date_picker.
Взгляните на это, прежде чем взламывать.
Как и Зубин, я видел это исключение, когда форма отправляла месяц как название месяца, а не числовую строку месяца (например, октябрь, а не 10).
Один пользовательский агент, с которым я столкнулся, похоже, отправляет содержимое тега option, а не атрибута value:
Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaE66-1/300.21.012; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413
Таким образом, в случае отправки даты с несколькими параметрами из сгенерированного помощником select (из помощника date_select) ваши параметры будут иметь:
"event"=> {
"start_on(2i)"=>"October",
"start_on(3i)"=>"19",
"start_on(1i)"=>"2010"
}
Это создает исключение: ActiveRecord :: MultiparameterAssignmentErrors: 1 ошибка (-ы) при назначении многопараметрических атрибутов
Большинство пользовательских агентов правильно отправят:
"event"=> {
"start_on(2i)"=>"10",
"start_on(3i)"=>"19",
"start_on(1i)"=>"2010"
}
Это не ошибка в Rails, это предполагаемое поведение средства записи многопараметрических атрибутов. Я готов поспорить, что исходное поле delivery_date в базе данных постера является varchar, а не типом date или datetime. ActiveRecord использует каждую часть многопараметрического атрибута для отправки новому методу сериализованного типа. Число 1, 2, 3 и т. д. Указывает положение параметра конструктора, а «i» указывает ActiveRecord вызвать to_i для параметра перед его передачей конструктору. В этом случае все они - «i», потому что DateTime.new (год, месяц, день) ожидает три целых числа, а не три строки.
Если столбец delivery_date в базе данных не является типом, сериализованным в DateTime, ActiveRecord выдаст исключение ActiveRecord :: MultiparameterAssignmentErrors, поскольку String.new (2010,2,11) не будет успешным.
Источник: https://github.com/rails/rails/blob/v3.0.4/activerecord/lib/active_record/base.rb#L1739
Спасибо, что действительно спасли положение. Система представляет собой очень старый портал, который все еще работает на рельсах 2.1.0 и не может быть обновлен, потому что даже рельсы исправлены / взломаны, а тестовое покрытие равно 0, так что это действительно стало удобно. Также добавлено количество хаков, необходимых для продолжения работы :)