Que signifie ActiveRecord :: MultiparameterAssignmentErrors?
-
01-07-2019 - |
Question
J'ai une forme de rails avec un champ datetime_select. Lorsque j'essaie de soumettre le formulaire, j'obtiens l'exception suivante:
ActiveRecord::MultiparameterAssignmentErrors in WidgetsController#update
1 error(s) on assignment of multiparameter attributes
S'il s'agit d'une erreur de validation, pourquoi ne puis-je pas voir une erreur sur la page?
Ceci est dans Rails 2.0.2
La solution
Il s'avère que les rails utilisent une méthode appelée affectation multiparamétrique pour transmettre des dates et des heures dans de petites pièces qui sont réassemblées lorsque vous affectez des paramètres à l'instance du modèle.
Mon problème était que j'utilisais un champ de formulaire datetime_select pour un champ de modèle de date. Cela s’étouffe apparemment lorsque la magie multiparamétrique tente de régler l’heure sur un objet Date.
La solution consistait à utiliser un champ de formulaire date_select
plutôt qu'un datetime_select
.
Autres conseils
Super, mais j'avais besoin de résoudre ce problème immédiatement pour un projet client. C'est toujours un bug avec Rails 2.3.5.
En utilisant date_select
ou datetime_select
, si vous ajoutez ceci à votre modèle dans la méthode initialize
, vous pouvez pré-analyser le formulaire transmis. attributs sérialisés pour le faire fonctionner:
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
Je l’utilise avec un modèle imbriqué, polymorphe. Voici une question que j'ai affichée sur les modèles que j'utilise . Il me fallait donc includes_nested_attributes_for
avec une date / heure.
Voici l'entrée et la sortie à l'aide de la console:
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
Sinon, c'était soit nul, soit l'erreur:
1 erreur (s) lors de l'attribution d'attributs multiparamètres
J'espère que ça aide, Lance
Ce n'est pas un bogue dans Rails, c'est le comportement voulu du rédacteur d'attributs à paramètres multiples. Je suis prêt à parier que le champ deliver_date de l'affiche originale dans la base de données est un varchar par opposition à un type de date ou de date / heure. ActiveRecord utilise chaque partie de l'attribut multi-paramètres pour envoyer à la nouvelle méthode du type sérialisé. Le nombre 1, 2, 3, etc. indique la position du paramètre du constructeur et le "i". indique à ActiveRecord d'appeler to_i sur le paramètre avant de le transmettre au constructeur. Dans ce cas, ils sont tous "i's". car DateTime.new (année, mois, jour) attend trois nombres entiers et non trois chaînes.
Si la colonne deliver_date de la base de données n'est pas un type sérialisé en DateTime, ActiveRecord lève une exception ActiveRecord :: MultiparameterAssignmentErrors car String.new (2010,2,11) n'aboutira pas.
Source: https://github.com/rails /rails/blob/v3.0.4/activerecord/lib/active_record/base.rb#L1739
ActiveRecord lève l'exception MultiparameterAssignmentErrors lorsque vous essayez de définir une date non valide pour un attribut de modèle.
Essayez de choisir une date du 31 novembre dans les listes déroulantes date_select ou datetime_select et vous obtiendrez cette erreur.
Comme Zubin, j’ai vu cette exception lorsque le formulaire envoie un mois sous la forme d’un nom de mois plutôt que d’une chaîne numérique (p. ex. octobre plutôt que 10).
Un agent utilisateur que j'ai rencontré semble soumettre le contenu de la balise d'option plutôt que l'attribut value:
Mozilla / 5.0 (SymbianOS / 9.2; U; Series60 / 3.1 NokiaE66-1 / 300.21.012; Profil / MIDP-2.0 Configuration / CLDC-1.1) AppleWebKit / 413 (KHTML, comme Gecko) Safari / 413
Ainsi, dans le cas où vous soumettez une date à paramètres multiples à partir d'un assistant généré, sélectionnez (à partir de l'assistant date_select) vos paramètres:
"event"=> {
"start_on(2i)"=>"October",
"start_on(3i)"=>"19",
"start_on(1i)"=>"2010"
}
Ceci crée une exception: ActiveRecord :: MultiparameterAssignmentErrors: 1 erreur (s) lors de l'attribution d'attributs multiparamètres
La plupart des agents d'utilisateur soumettront correctement:
"event"=> {
"start_on(2i)"=>"10",
"start_on(3i)"=>"19",
"start_on(1i)"=>"2010"
}
Cette erreur peut également se produire avec webrat / cucumber lors du remplissage de données de formulaire à l'aide d'une table.
Par exemple, cela ne fonctionne pas:
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 |
mais cela fait:
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 |
Dans mon cas, le plug-in am / pm d’ActiveRecord a provoqué l’erreur via une chaîne alias_method_chain
incorrecte, ce qui a généré une exception StackLevelTooDeep
.
Le plugin a été inclus par le plugin unobtrusive_date_picker.
Le regard sur cela avant de pirater.