Porbleme de relation

J’aimerai creer une zone membre avec une simple relation entre mes deux
tables:

explication:
un membre peut creer plusieurs recettes de cuisines et j’aimerai qu’il
puisse a la fois voir ses propres recettes et a la fois que ces recettes
soient melangé a toutes les recettes créées.

J’ai donc créé deux table:
La table recette a un champ “user_id INT(11) NOT NULL” qui est une clef
etrangere envers la table “users”
De plus mon model recette contient : has_many :users
et mon model user contient : belongs_to :recettes

quand je veux creer une nouvelle recette rails m’indique :
“Mysql::Error: #23000Column ‘user_id’ cannot be null: INSERT INTO
recettes (Titre, image_url, Alias, Ingredients, Date,
user_id, Description) VALUES(‘Abricots’, ‘’, ‘Gary’, '3 abricots, 2
pommes, ', ‘2007-07-03 16:59:00’, NULL, ‘melanger le tout’)”

Que dois-je faire, merci par avance pour votre précieuse aide.

Cordialement,

On 7/3/07, Gary [email protected] wrote:

La table recette a un champ “user_id INT(11) NOT NULL” qui est une clef
Que dois-je faire, merci par avance pour votre précieuse aide.

Cordialement,

Ton problème est un problème SQL. En effet il y a deux moyens pour
créer un objet ActiveRecord en BDD :

Object.create
Object.new

Dans le premier cas ActiveRecord fait un enregistrement direct en BDD.
Dans le deuxième cas il n’y aura un enregistrement que si tu le dis
explicitement avec un save.

Je suppose que ton erreur arrive quand tu fais un create. En effet, au
vu de la configuration de ta BDD? tu es toujours obligé de lier un
utilisateur avec une recette au moment de l’enregistrement en BDD
(save ou create). Si tu ne l’as pas fait alors RAILS tente de mettre à
NULL le champs mais la BDD n’en veux pas car tu as mis à NOT NULL.

Tu as donc deux choix :

  1. mettre ton champs user_id possible à NULL
  2. faire une méthode before_create qui vérifie qu’un utilisateur est
    défini sinon le met à 0, mais alors il faut gérer encore plein d’autre
    cas après.


Cyril M.

Effectivement quand le user_id est NULL ruby accepte le create par
contre il n’y a aucune donnée stocké dans le champs user_id donc aucun
lien avec la table user ou tout simplement rien ne specifie que la
recette appartient au user qui l’a créé…
J’utilise le plug in :“before_filter :login_required”…

Que faire?
Et merci encore Cyril M. pour ta reponse

Cordialement
Cyril M. wrote:

On 7/3/07, Gary [email protected] wrote:

La table recette a un champ “user_id INT(11) NOT NULL” qui est une clef
Que dois-je faire, merci par avance pour votre pr�cieuse aide.

Cordialement,

Ton probl�me est un probl�me SQL. En effet il y a deux moyens pour
cr�er un objet ActiveRecord en BDD :

Object.create
Object.new

Dans le premier cas ActiveRecord fait un enregistrement direct en BDD.
Dans le deuxi�me cas il n’y aura un enregistrement que si tu le dis
explicitement avec un save.

Je suppose que ton erreur arrive quand tu fais un create. En effet, au
vu de la configuration de ta BDD? tu es toujours oblig� de lier un
utilisateur avec une recette au moment de l’enregistrement en BDD
(save ou create). Si tu ne l’as pas fait alors RAILS tente de mettre �
NULL le champs mais la BDD n’en veux pas car tu as mis � NOT NULL.

Tu as donc deux choix :

  1. mettre ton champs user_id possible � NULL
  2. faire une m�thode before_create qui v�rifie qu’un utilisateur est
    d�fini sinon le met � 0, mais alors il faut g�rer encore plein d’autre
    cas apr�s.


Cyril M.

Voici mes deux tables:

CREATE TABLE recettes (
Titre varchar(100) NOT NULL,
Ingredients text NOT NULL,
id int(11) NOT NULL auto_increment,
Description text NOT NULL,
Date datetime NOT NULL,
image_url varchar(200) NOT NULL,
Alias varchar(50) NOT NULL,
user_id int(11) default NULL,
PRIMARY KEY (id),
KEY fk_recettes_users (user_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

et

CREATE TABLE users (
id int(11) NOT NULL auto_increment,
login varchar(80) default NULL,
password varchar(40) default NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

Ma recette est créée par :

def new
@recette = Recette.new

end

def create

@recette = Recette.new(params[:recette])
if @recette.save
  flash[:notice] = 'Recette créé avec succès.'
  redirect_to :action => 'list'
else
  render :action => 'new'
end

end

et ca plante dés que je “create” ma recette.

Merci encore
Cyril M. wrote:

On 7/3/07, Gary [email protected] wrote:

Effectivement quand le user_id est NULL ruby accepte le create par
contre il n’y a aucune donn�e stock� dans le champs user_id donc aucun
lien avec la table user ou tout simplement rien ne specifie que la
recette appartient au user qui l’a cr��…
J’utilise le plug in :“before_filter :login_required”…

Que faire?

Comment cr�e tu par exemple ta recette dans ta BDD ?

rempli tu l’attribut user ou user_id ?

Ca plante avant ou apr�s avoir assign� ces valeurs ?


Cyril M.

On 7/3/07, Gary [email protected] wrote:

Effectivement quand le user_id est NULL ruby accepte le create par
contre il n’y a aucune donnée stocké dans le champs user_id donc aucun
lien avec la table user ou tout simplement rien ne specifie que la
recette appartient au user qui l’a créé…
J’utilise le plug in :“before_filter :login_required”…

Que faire?

Comment crée tu par exemple ta recette dans ta BDD ?

rempli tu l’attribut user ou user_id ?

Ca plante avant ou après avoir assigné ces valeurs ?


Cyril M.

On 7/3/07, Gary [email protected] wrote:

Alias varchar(50) NOT NULL,
password varchar(40) default NULL,
def create
et ca plante dés que je “create” ma recette.
Ok, donc ton problème doit surement venir de ta vue de new. En effet,
on peux supposer que tu ne récupères pas de paramètres :
params[:recette][:user_id].

Si dans ta page new il n’y a pas de champs select pour définir ton
user alors ton problème vient tout simplement de là. Tu ne donnes
jamais d’utilisateur à ton objet recette. un petit :

recette.user_id = ‘id de ton user actuel’


Cyril M.

Il y a plusieurs facon de résoudre ton pb mais ils dépendent de la
facon dont tu as designé ton appli.
Je suppose que ta classe User à un “has_many recettes”
Dans ce cas au lieu de faire:

@recette = Recette.new(params[:recette])

c mieux de faire
@recette = current_user.recettes.build params[:recette]

Cela ajoutera ton champ user_id automatiquement.

Tu peux aussi avoir des routes REST nested qui feront aussi ce que tu
veux
map.resources :users do |user|
user.resources :recettes
end

Mais on ne va pas faire un cours complet rails dans la Mailing-List :slight_smile:

Seb

http://jobalize.com/fr
http://www.forum-rails.com

J’ai pas détaillé mais current_user fait référence à un user qui sait
identifié sur le site. (en général avec acts_as_authenticated ou
restful_authentication, tu as un “current_user”)
donc tu remplaces current_user par qqch qui pointe sur ton user courant.
Suis-je clair?

On 7/4/07, Gary B.attar [email protected] wrote:

else
  render :action => 'new'
end

end
et voici l’erreur:

undefined local variable or method `current_user’ for
#ListController:0xb69caa5c

Je pense qu’il faut que tu fasses un objet User de ton model pour
définir ce qu’est current_user.


Cyril M.

Pour faciliter le tout, j’ai installé Acts as Authenticated, mais ca ne
marche quand meme pas, il ne trouve pas current_user, de plus il ne se
souvient jamais que je suis deja logger et il me redemande a chaque fois
que je veux creer une nouvelle recette ( before_filter :login_required,
:only => [ :new ]), j’aimerais qu’il me le demande que quand je ne suis
pas logger…

Que faire
Merci

Cyril M. wrote:

On 7/4/07, Gary B.attar [email protected] wrote:

else
  render :action => 'new'
end

end
et voici l’erreur:

undefined local variable or method `current_user’ for
#ListController:0xb69caa5c

Je pense qu’il faut que tu fasses un objet User de ton model pour
d�finir ce qu’est current_user.


Cyril M.

Merci sebastien mais ca ne marche toujours pas: voila ce que j’ai fait:
dans le controller list_controller.rb
def create

@recette = current_user.recettes.build params[:recette]

if @recette.save
  flash[:notice] = 'Recette créé avec succès.'
  redirect_to :action => 'list'
else
  render :action => 'new'
end

end
et voici l’erreur:

undefined local variable or method `current_user’ for
#ListController:0xb69caa5c

avec belongs_to :users et has_many :recettes

Merci encore…

Sébastien Gruhier wrote:

Il y a plusieurs facon de résoudre ton pb mais ils dépendent de la
facon dont tu as designé ton appli.
Je suppose que ta classe User à un “has_many recettes”
Dans ce cas au lieu de faire:

@recette = Recette.new(params[:recette])

c mieux de faire
@recette = current_user.recettes.build params[:recette]

Cela ajoutera ton champ user_id automatiquement.

Tu peux aussi avoir des routes REST nested qui feront aussi ce que tu
veux
map.resources :users do |user|
user.resources :recettes
end

Mais on ne va pas faire un cours complet rails dans la Mailing-List :slight_smile:

Seb
http://xilinus.com
http://jobalize.com/fr
http://www.forum-rails.com

Probleme resolu merci a vous tous :

@recette = Recette.new(params[:recette])
@recette.user_id = current_user.id

if @recette.save
  flash[:notice] = 'Recette créé avec succès.'
  redirect_to :action => 'list'
else
  render :action => 'new'
end

end

Gary B.attar wrote:

Pour faciliter le tout, j’ai installé Acts as Authenticated, mais ca ne
marche quand meme pas, il ne trouve pas current_user, de plus il ne se
souvient jamais que je suis deja logger et il me redemande a chaque fois
que je veux creer une nouvelle recette ( before_filter :login_required,
:only => [ :new ]), j’aimerais qu’il me le demande que quand je ne suis
pas logger…

Que faire
Merci

Cyril M. wrote:

On 7/4/07, Gary B.attar [email protected] wrote:

else
  render :action => 'new'
end

end
et voici l’erreur:

undefined local variable or method `current_user’ for
#ListController:0xb69caa5c

Je pense qu’il faut que tu fasses un objet User de ton model pour
d�finir ce qu’est current_user.


Cyril M.

Kool

Si tu as current_user maintenant tu peut faire

current_user.recettes.build params[:recette]

c’est plus propre je trouve sinon tu peux aussi faire

@recette = Recette.new(params[:recette].merge(:user_id =>
current_user.id)

Pour Acts as Authenticated il te suffit d’activer la fonction
“remember me”

Seb

http://jobalize.com/fr
http://www.forum-rails.com

Juste encore une petite chose, je veux maintenant afficher dans une
page “listmembre” seulement les recettes de mon user connecté ( j’ai
activé la fonction “remember me”.

def listmembre
@recette_pages, @recettes = Recette.find(:all, :conditions =>
“user_id = user.id”)
end
et dans ma vue:

<% for recette in @recettes %>

et cela ne marche pas comment faire?
J’ai une champs user_id dans ma table recettes qui stocke le id de
chaque user de la table users…

Merci beaucoup…
Sébastien Gruhier wrote:

Kool

Si tu as current_user maintenant tu peut faire

current_user.recettes.build params[:recette]

c’est plus propre je trouve sinon tu peux aussi faire

@recette = Recette.new(params[:recette].merge(:user_id =>
current_user.id)

Pour Acts as Authenticated il te suffit d’activer la fonction
“remember me”

Seb
http://xilinus.com
http://jobalize.com/fr
http://www.forum-rails.com

Tu melanges ton code avec celui de la pagination il me semble
le mieux est de faire
def list
@recettes = current_user.recettes
end

Seb

On 7/5/07, Gary B.attar [email protected] wrote:

Juste encore une petite chose, je veux maintenant afficher dans une
page “listmembre” seulement les recettes de mon user connecté ( j’ai
activé la fonction “remember me”.

def listmembre
@recette_pages, @recettes = Recette.find(:all, :conditions =>
“user_id = user.id”)

@recette_pages, @recettes = Recette.find(:all, :conditions =>
[“user_id = ?”, current_user.id])

end
et dans ma vue:

<% for recette in @recettes %>

et cela ne marche pas comment faire?
J’ai une champs user_id dans ma table recettes qui stocke le id de
chaque user de la table users…


Cyril M.

Genial! Merci sebastien

Sébastien Gruhier wrote:

Tu melanges ton code avec celui de la pagination il me semble
le mieux est de faire
def list
@recettes = current_user.recettes
end

Seb