Forum: Rails France Insertion dans une table avec une clé primaire varchar

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
The Allnighter (Guest)
on 2006-05-23 16:41
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: <!--[form:candidat]-->                                            |
4:                                                                   |
5: <p><label for="candidat_CIN">CIN</label><br/>                     |
6: <%= text_field 'candidat', 'CIN'  %></p>                          |
7:                                                                   |
8: <p><label for="candidat_NOM_CANDIDAT">Nom</label><br/>            |
9: <%= text_field 'candidat', 'NOM_CANDIDAT'  %></p>                 |
_____________________________________________________________________|

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.
Thomas (Guest)
on 2006-05-23 19:04
Comment as tu codé ta classe Candidat ? As tu bien utilisé la méthode
set_primary_key ?

A+
The Allnighter (Guest)
on 2006-05-23 20:01
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
Thomas (Guest)
on 2006-05-23 22:13
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+
Thomas (Guest)
on 2006-05-23 22:17
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
The Allnighter (Guest)
on 2006-05-24 01:30
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:in `method_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]:
<false> is not true.                                                 |
_____________________________________________________________________|

Merci pour votre aide
Renaud (Nel) Morvan (Guest)
on 2006-05-24 02:48
(Received via mailing list)
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= :)
Jean-François (Guest)
on 2006-05-24 03:44
(Received via mailing list)
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= :)

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 :)

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.
Frederick R. (Guest)
on 2006-05-24 08:58
(Received via mailing list)
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/lega...


--
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)
The Allnighter (Guest)
on 2006-05-29 22:16
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
Mathieu A. (Guest)
on 2006-05-30 11:58
(Received via mailing list)
+-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])
?
This topic is locked and can not be replied to.