2014-06-19 2 views
7

Voici mon schema.rbRails 4 Migration: mysql2 :: Erreur: données trop long pour la colonne 'xxxx'

create_table "users", force: true do |t| 
    t.string "name",  limit: 6 
    t.string "email" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

Je mets la limite fo chaîne pour la colonne "nom".

Puis, dans la console:

user = User.new(name:"1234567890",email:"[email protected]") 
user.save! 

Il a soulevé l'erreur:

ActiveRecord::StatementInvalid: Mysql2::Error: Data too long for column 'name' at row 1: INSERT INTO `users` (`created_at`, `email`, `name`, `updated_at`) VALUES ('2014-06-19 15:08:15', '[email protected]', '1234567890', '2014-06-19 15:08:15') 

Mais, quand je suis passé à rails 3.

je l'ai trouvé tronqué la chaîne "" automatiquement, et inséré "" dans la base de données sans erreur.

Y at-il quelque chose à ce sujet a été retiré dans rails 4?

Dois-je ajouter quelques fonctions tronquées dans le modèle par moi-même? Merci!

+1

Pour la dernière question, il peut dépendre de votre cas d'utilisation pour la création 'user'. Peut-être qu'il serait peut-être préférable d'ajouter un validateur pour vérifier la longueur sur ': name' et afficher une erreur à l'utilisateur s'il se termine trop longtemps? –

+0

La validation est probablement la voie à suivre, car un utilisateur doit savoir que son nom ne peut pas dépasser 6 caractères. Sinon, ils pourraient être surpris quand ils entrent dans "Jonathan" mais quand ils regardent leur profil, leur nom est listé comme "Jonath". –

+0

Merci, je comprends que le meilleur moyen est d'ajouter une validation. Mais je veux juste comprendre ce qui a été changé dans Rails 4, et j'ai certains modèles sont invisibles pour les utilisateurs, donc dans ce cas, la validation ne peut pas m'aider. – tzzzoz

Répondre

16

Ce que vous voyez est une différence dans MySQL, pas Rails. Par défaut, MySQL tronquera les données trop longues au lieu de lancer une erreur. Si vous définissez MySQL en mode strict, il va lancer des erreurs au lieu de tronquer silencieusement les données.

Avec la version 4, Rails turns on strict mode par défaut. C'est pourquoi vous voyez un comportement différent avec Rails 3. Ce est le comportement que vous voulez probablement. La troncation silencieuse des données est presque toujours mauvaise et peut conduire à un comportement très confus pour les utilisateurs.

Si vous vraiment voulez tronquer les données, vous pouvez turn off strict mode ou utiliser un filtre avant:

before_save :truncate_username 
def truncate_username 
    self.username = username.slice(0, 6) 
end 
+0

Merci, c'est utile! Lifesaver – tzzzoz

7

J'ai trébuché sur this article coïncidement écrit il y a seulement quelques jours.

Le principal point d'intérêt est la suivante:

...I recently upgraded from rails 3.2 to rails 4.0. They implemented a major change with ActiveRecords that I can find no mention of any where except in the source and change log.

  • mysql and mysql2 connections will set SQL_MODE=STRICT_ALL_TABLES by default to avoid silent data loss. This can be disabled by specifying strict: false in your database.yml .

Cela semble expliquer pourquoi vous ne recevez plus l'erreur lorsque vous est revenu à Rails 3. Vous pouvez le voir dans les options du MySQL connection adapter module et il semble que ce soit added way back in May 2012 pour le candidat à la version 4.1.2 (si je lis correctement les balises).

Cette personne a résolu son problème par le code ... [fixant] pour avoir les bonnes longueurs de champ, ou tronquer manuellement les données ....

Dans votre cas, vous pouvez peut-être résoudre votre problème avec Rails 4 simplement en ajoutant strict: false à votre database.yml. Si vous souhaitez personnaliser la façon dont les données sont tronquées, je suis d'accord avec la suggestion de JKen13579 concernant le rappel before_save. Sinon, d'après ce que je peux voir, il semble tronquer les caractères les plus à droite, donc si cela est suffisant, vous pouvez probablement vous en passer avec le comportement de troncature par défaut.

+1

Merci, c'est clair pour moi! – tzzzoz

+1

Cette réponse ne pointe pas seulement vers un article qui explique réellement quel est le vrai problème. Après l'avoir lu, vous pouvez également voir pourquoi il suffit de découper vous-même des données sur la migration. Grande réponse @ paul-richter – josethernandezc

Questions connexes