2010-04-28 4 views
2

J'ai un modèle de rails auquel j'ajoute des validations et j'ai l'impression d'avoir rencontré un peu d'étrangeté de l'un des validateurs.Rails validates_length_of se comporte mal

Voici donc la table, je travaille avec (De schema.rb):

create_table "clients", :force => true do |t| 
    t.string "name" 
    t.string "last_contact" 
    t.integer "contacting_agent" 
    t.date  "last_payment_date" 
    t.float "last_payment_amt" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    t.string "office" 
    t.integer "client_id" 
    end 

J'ai une vue normale, avec:

<%= error_messages_for 'client' %> 
<h1>New Client</h1> 
<% form_for @client do |new| %> 

<table id='newform'> 
<tr> 
    <th>Field</th> 
    <th>Value</th> 
</tr> 
<tr> 
    <td> 
    ID 
    </td> 
    <td> 
    <%= new.text_field :client_id %> 
    </td> 
</tr> 
<tr> 
    <td> 
    Name 
    </td> 
    <td> 
    <%= new.text_field :name %> 
    </td> 
</tr> 
<tr> 
    <td> 
    Office 
    </td> 
    <td> 
    <%= new.select :office, $offices %> 
    </td> 
</tr> 
<tfoot> 
    <tr> 
    <td> 
    <%= image_submit_tag "/images/icons/save_32.png" %> 
    <a href="/clients/new" title="Clear"><%= image_tag "/images/icons/close_32.png" %></a> 
    </td> 
    <td> 
    &nbsp; 
    </td> 
    </tr> 
</tfoot> 
</table> 

<% end %> 

et mon humble modèle

class Client < ActiveRecord::Base 
    validates_length_of :client_id, :in => 5..7 
    validates_uniqueness_of :client_id 
    validates_presence_of :name, :client_id 
end 

Donc la partie qui donne un coup de pied à mes fesses est la première validation dans le modèle.

validates_length_of :client_id, :in => 5..7 

Si je pars vers le navigateur et la charge de la vue (/ clients/nouveaux), j'entrer dans une client_id et un nom, sélectionnez un bureau, puis appuyez sur soumettre. Le validateur ne prend pas correctement le :client_id, car il échouera toujours avec les messages d'erreur "trop ​​court" ou "trop ​​long".

Le kicker est qu'il me donnera l'erreur "trop ​​courte" jusqu'à ce que j'essaie environ 11 caractères, puis à 12 caractères, je reçois le "trop ​​long". Donc, 11 est le seuil de "trop ​​court", même si la plage est supposée être "5..7" - mais parfois au lieu du message "trop ​​long", il validera et insérera l'enregistrement, mais l'enregistrement inserts a un numéro complètement différent pour "client_id", et c'est toujours pareil, malgré le validates_uniqueness_of. Ce que je pense qui se passe est que :client_id, au lieu de valider le champ réel, client_id, il essaie de ramasser l'id d'objets, et de valider cela. Au moins, c'est la seule chose à laquelle je peux penser.

Parameters: {"x"=>"13", "y"=>"14", "authenticity_token"=>"removed", "client"=>{"name"=>"test345", "client_id"=>"12345678", "office"=>"US10"}} 

Ci-dessus, à partir des journaux de serveur, valide comme « trop court » pour :client_id

Alors s'il vous plaît, est-il possible de corriger cette bizarrerie? (Note: J'ai essayé validates_length_of "client_id", :in => 5..7 mais n'ai absolument aucune validation)

Répondre

1

client_id colonne est un nombre entier. validates_length_of utilise la méthode size pour trouver la longueur du champ, et pour l'entier, il vous donne juste la taille de la variable en octets, qui est probablement 4 pour les 11 premiers "caractères" et 8 pour 12+.

Si vous avez vraiment besoin CLIENT_ID être entier et de valider la longueur, vous pouvez probablement utiliser:

validates_inclusion_of :client_id, :in => 10000..9999999, :message => "should be between 5 and 7 characters" 
+0

Merci de remarquer que sur moi. Semble clair comme le jour maintenant lol. Je vais simplement passer à 'validates_format_of: client_id,: avec =>/\ A \ d {5,7} \ z /' et utiliser regex. –

+0

S'il s'agit d'une colonne Integer dans la base de données, 'validates_inclusion_of' ne fonctionnera pas car la valeur du formulaire est une chaîne. Vous voulez 'validates_numericality_of' avec les options': greater_than_or_equal_to' et ': less_than_or_equal_to'. –

+0

En fait, ce sera le cas, car la valeur est transformée en nombre entier lorsque le champ est affecté. '>> c = Client.new (: client_id =>" 22222 ")'; '>> c.client_id'; '=> 22222' – Voyta

Questions connexes