Insertion dans une table avec une clé primaire varchar


#1

Bonjour,
Je travaille actuellement sur un projet de migration d’une application
Coldfusion vers Rails.
Le problème se manifeste au moment de l’insertion dans une table qui a
une clé primaire de type varchar(15)!!! ci-dessous le schéma de la
table:
CREATE TABLE chercheur (
CIN varchar(15) NOT NULL default ‘’,
DATE_INSCRIPTION datetime default NULL,
NOM_CANDIDAT varchar(50) default NULL,
PRENOM varchar(50) default NULL,
PRIMARY KEY (CIN),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

voici le message d’arreur que j’ai quand j’essaie de remplir la table
depuis un formulaire :


undefined method `CIN_before_type_cast’ for #Candidat:0x370d8c8 |
|
Extracted source (around line #6): |
|
3: |
4: |
5:

CIN
|
6: <%= text_field ‘candidat’, ‘CIN’ %>

|
7: |
8:

Nom
|
9: <%= text_field ‘candidat’, ‘NOM_CANDIDAT’ %>

|
_____________________________________________________________________|

J’ai du ajouter alors les deux méthodes suivantes au Modele (Candidat):


                                                                 |

def CIN_before_type_cast |
read_attribute(:CIN) |
end |
|
def CIN_before_type_cast=(input) |
write_attribute(:CIN, input) |
end |
_____________________________________________________________________|

En réessayant cette fois j’ai le message d’erreur :


                                                                 |

1 error prohibited this candidat from being saved |
There were problems with the following fields: |
* Cin can’t be blank |
_____________________________________________________________________|

Merci pour votre aide, je suis novice et je suis bloqué sur ce problème
depuis plusieurs jours maintenant.


#2

Comment as tu codé ta classe Candidat ? As tu bien utilisé la méthode
set_primary_key ?

A+


#3

Thomas wrote:

Comment as tu codé ta classe Candidat ? As tu bien utilisé la méthode
set_primary_key ?

A+

Merci pour ta réponse Thomas, voici le modèle Candidat :
class Candidat < ActiveRecord::Base
set_table_name “CHERCHEUR”
set_primary_key “CIN”

#validations
validates_presence_of :CIN, :NOM_CANDIDAT, :PRENOM, :PASSWORD
validates_uniqueness_of :CIN
validates_format_of :E_MAIL,
:with =>
/^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i

def CIN_before_type_cast
read_attribute(:CIN)
end

def CIN_before_type_cast=(input)
write_attribute(:CIN, input)
end
end


#4

Je vois pas trop la. Le seul truc que je peux te dire c’est que le
dernier message d’erreur que tu obtiens : Cin can’t be blank fait suite
à la validation de ton candidat quand tu essaies de le persister et est
le message d’erreur correspondant à validates_presence_of :CIN.

Balance le code de ton controleur à tout hasard …

A+


#5

Ah oui, j’oubliais, fais toi un petit test unitaire ds lequel tu essaies
de persister un objet Candidat que tu instancies toi même genre :

c = Candidat.new
c.CIN = …
c.NOM = …
assert c.save()

Ca te permettra au pire de mieux localiser ton problème

A+ et bonne chance


#6

The A. wrote:

Thomas wrote:

Comment as tu codé ta classe Candidat ? As tu bien utilisé la méthode
set_primary_key ?

A+

Merci pour ta réponse Thomas, voici le modèle Candidat :
class Candidat < ActiveRecord::Base
set_table_name “CHERCHEUR”
set_primary_key “CIN”

Petite subtilité pour setter une clé primaire il faut utiliser id= :slight_smile:


#7

voici le test unitaire que j’ai ajouté :


def test_create_new_candidat |
c = Candidat.new |
c.CIN = “BH312541” |
c.NOM_CANDIDAT = “Gogo” |
c.PRENOM = “toto” |
c.PASSWORD = “wibble” |
assert c.save() |
end |
_____________________________________________________________________|

j’ai alors ce message qui s’affiche :


Started |
E |
Finished in 0.44 seconds. |

  1. Error: |
    test_create_new_candidat(CandidatTest): |
    NoMethodError: undefined method CIN=' for #<Candidat:0x3a86c78> | c:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.2/lib/active_record | /base.rb:1789:inmethod_missing’ |
    test/unit/candidat_test.rb:19:in `test_create_new_candidat’ |
    1 tests, 0 assertions, 0 failures, 1 errors |
    _____________________________________________________________________|
    j’ai dû donc ajouter cette méthode dans le modèle Candidat :

def CIN |
read_attribute(:CIN) |
end |
|
def CIN=(input) |
write_attribute(:CIN, input) |
end |
_____________________________________________________________________|
je relance le test …


  1. Failure: |
    test_create_new_candidat(CandidatTest) [test/unit/candidat_test.rb:23]:
    is not true. |
    _____________________________________________________________________|

Merci pour votre aide


#8

The A. wrote :
| voici le test unitaire que j’ai ajouté :
| _____________________________________________________________________
| def test_create_new_candidat |
| c = Candidat.new |
| c.CIN = “BH312541” |
| c.NOM_CANDIDAT = “Gogo” |
| c.PRENOM = “toto” |
| c.PASSWORD = “wibble” |
| assert c.save() |
| end |
| _____________________________________________________________________|
|

Pour ce qui est de s’interfacer avec une data base déjà existante, et
avec une autre convention il faut un peu bidouiller … mais on y arrive

J’ai commencé à écrire un truc il y a qq temps là -dessus, si ça
t’intéresse:

http://sl33p3r.free.fr/tutorials/rails/legacy/legacy_databases.html


Frederick R. aka Sleeper – removed_email_address@domain.invalid

Don’t sacrifice clarity for small gains in “efficiency”.
- The Elements of Programming Style (Kernighan & Plaugher)


#9

Bonjour,
Merci à vous tous pour votre précieuse aide.
j’ai trouvé un work-around pour contourner ce problème. dans le
controlleur Candidat, j’ai ajouté les lignes suivantes au lieu de
@candidat = Candidat.new(params[:candidat]) :
@candidat = Candidat.new()
@candidat.CIN = params[:candidat][:CIN]
@candidat.NOM_CANDIDAT = params[:candidat][:NOM_CANDIDAT]
@candidat.PRENOM = params[:candidat][:PRENOM]
@candidat.PASSWORD = params[:candidat][:PASSWORD]

cette méthode est plus longue certe et surtout moins élégante, mais elle
permet de débloquer le problème. j’avait remarqué que les requetes
“Insert into” généré par rails ne contenaient pas le champ (CIN) clé de
la table Candidat.
Jean-François,
le champ email n’est pas obligatoire, comment je peux le checker que
s’il n’est pas vide? Merci


#10

2006/5/24, Renaud (Nel) Morvan removed_email_address@domain.invalid:

The A. wrote:

Merci pour ta réponse Thomas, voici le modèle Candidat :
class Candidat < ActiveRecord::Base
set_table_name “CHERCHEUR”
set_primary_key “CIN”

Petite subtilité pour setter une clé primaire il faut utiliser id= :slight_smile:

Tout à fait, on a 1 setter contre 2 getters #id et #CIN. C’est assez
piégeux.

Remarques pour Allnighter : tu peux tester ton modèle dans
script/console. C’est pas que les tests unitaires, c’est pas bien,
mais c’est pratique et nettement plus interactif :slight_smile:

A propos de ces lignes :

validates_format_of :E_MAIL,
:with =>
/^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i

Je suppose que tu te contentes de vérifier des adresses
en : removed_email_address@domain.invalid
Tu as intérêt à bien tester l’expression rationnelle auparavant,
exemple :

irb(main):002:0> re = /^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i
=> /^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i
irb(main):003:0> re.match(‘removed_email_address@domain.invalid’)
=> #MatchData:0x84058
irb(main):004:0> re.match(“hello\removed_email_address@domain.invalid\nworld
!!\nblah,blah,blah…”)
=> #MatchData:0x78a78
irb(main):005:0> re.match(“hello\removed_email_address@domain.invalid”)
=> #MatchData:0x6e2a8
irb(main):006:0> re.match(“removed_email_address@domain.invalid\nhello world !!”)
=> #MatchData:0x65b30
irb(main):007:0> re.match(“hello world !!”)
=> nil

C’est un peu mieux comme ça…

irb(main):008:0> re = /\A([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})\z/i
=> /\A([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})\z/i
irb(main):009:0> re.match(‘removed_email_address@domain.invalid’)
=> #MatchData:0x4fba0
irb(main):010:0> re.match(“hello\removed_email_address@domain.invalid\nworld
!!\nblah,blah,blah…”)
=> nil
irb(main):011:0> re.match(“removed_email_address@domain.invalid\nhello world !!”)
=> nil
irb(main):012:0> re.match(“hello world !!”)
=> nil

… mais il y a encore des choses à améliorer :

irb(main):013:0> re.match(“toto<>&?/@coucou.fr”)
=> #MatchData:0x3e670
irb(main):014:0>

   -- Jean-François.

#11

±Le 29/05/2006 20:16 +0200, The A. a dit :
| Bonjour,
| Merci à vous tous pour votre précieuse aide.
| j’ai trouvé un work-around pour contourner ce problème. dans le
| controlleur Candidat, j’ai ajouté les lignes suivantes au lieu de
| @candidat = Candidat.new(params[:candidat]) :
| @candidat = Candidat.new()
| @candidat.CIN = params[:candidat][:CIN]
| @candidat.NOM_CANDIDAT = params[:candidat][:NOM_CANDIDAT]
| @candidat.PRENOM = params[:candidat][:PRENOM]
| @candidat.PASSWORD = params[:candidat][:PASSWORD]
|
| cette méthode est plus longue certe et surtout moins élégante

@candidat = Candidat.new(params[:candidat])
?