JeuWeb - Crée ton jeu par navigateur
[Rails] Problème après rechargement de formulaire avec autocomplétion en cas d'erreur - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Rails] Problème après rechargement de formulaire avec autocomplétion en cas d'erreur (/showthread.php?tid=5785)



[Rails] Problème après rechargement de formulaire avec autocomplétion en cas d'erreur - popayan - 02-11-2011

Bonjour à tous (et surtout à Sephi ConfusediffleSmile

Je dois vraiment être une quiche et faire (encore) n'importe quoi...

donc tout d'abord un peu de code :

La vue

%h1= "Nouveau Message"

= form_for @message do |f|
%p.double
= f.label :receiver
= f.text_field :receiver
= show_errors_message(@message.errors[:receiver])
%p.double
= f.label :title
= f.text_field :title
= show_errors_message(@message.errors[:title])
%p.double
= f.label :body
= f.text_area :body
= show_errors_message(@message.errors[:body])

= f.submit

Le modèle

class Message < ActiveRecord::Base
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
belongs_to :receiver, :class_name => "User", :foreign_key => "receiver_id"

validates_presence_of :author, :receiver, :title, :body
end
et enfin, la méthode create de mon controlleur

def create
username = params[:message][:receiver]
params[:message][:receiver] = User.find_by_username(username)
@message = Message.new params[:message]
@message.author = current_user
if @message.save
redirect_to messages_path
else
render 'new'
end
end

Je passe sur le javascript (auto_completion) qui me remplie le champ "receiver".
Quand on remplit correctement le formulaire, tout se passe bien. par contre si je remplis le champ receiver et pas le reste, le formulaire n'est pas validé et au moment de réafficher le formulaire, le champ receiver vaut quelque chose du style #<User:0x286b870>! Alors, je comprends bien pourquoi mais je ne trouve pas comment le corriger... (J'ai fait pas mal de test en bidouillant mais rien n'a réellement fonctionné)


RE: [Rails] Problème après rechargement d'un formulaire en cas d'erreur - Sephi-Chan - 02-11-2011

Premièrement, tu peux changer ton modèle pour :


class Message < ActiveRecord::Base
belongs_to :author, class_name: "User"
belongs_to :receiver, class_name: "User"

validates_presence_of :author, :receiver, :title, :body
end

En effet, les foreign keys sont devinées depuis le nom de l'association.


Ensuite, ton problème survient parce que ton champ de formulaire accepte un objet User et que tu y demandes une chaîne de caractère. le type de champ n'est pas très fidèle à son contenu.


RE: [Rails] Problème après rechargement d'un formulaire en cas d'erreur - popayan - 02-11-2011

Ca, je l'ai bien compris! Par contre, je suis obligé de travailler sur une chaine de caractère dans ce champ à cause de l'autocomplétion... C'est pour ça que je récupère un objet User via la chaine de caractère. Le problème est que je ne peux pas faire marche arrière (remettre du texte) dans ce champ en cas d'erreur...
Je dois mal faire quelque chose...


RE: [Rails] Problème après rechargement d'un formulaire en cas d'erreur - Sephi-Chan - 02-11-2011

Tu peux fonctionner avec un id puisque le véritable attribut est receiver_id : les scripts d'autocompletion (genre jQuery UI Autocomplete) permettent d'avoir une valeur (dans ton cas, l'id) et un libellé (le nom de l'utilisateur).

Dans tous les cas, je pense que tu auras besoin d'avoir un affichage différent lors de l'échec de validation. Par exemple en cas d'erreur de validation sur le receiver_id, tu as affiches le champ avec l'auto-complétion comme tu le faisais avant que la validation n'échoue, sinon tu le préremplis.

A voir selon ce que tu as client side. Smile


RE: [Rails] Problème après rechargement d'un formulaire en cas d'erreur - popayan - 02-11-2011

(02-11-2011, 12:55 PM)Sephi-Chan a écrit : Dans tous les cas, je pense que tu auras besoin d'avoir un affichage différent lors de l'échec de validation. Par exemple en cas d'erreur de validation sur le receiver_id, tu as affiches le champ avec l'auto-complétion comme tu le faisais avant que la validation n'échoue, sinon tu le préremplis.

Et c'est bien là mon problème... :langue2:



RE: [Rails] Problème après rechargement d'un formulaire en cas d'erreur - Sephi-Chan - 02-11-2011

En gros :


class MessagesController < ApplicationController
def new
@message = Message.new
end

def create
receiver_name = params.delete(:receiver_name)
@message = Message.new(params[:message])
@message.receiver = User.find_by_name(receiver_name)

if @message.save
redirect_to @message
else
render :new
end
end
end


Et la vue :


= form_for @message do |f|
%p
= label_tag :receiver_name
= text_field_tag :receiver_name, f.object.receiver.try(:name)
= errors_for(f.object, :receiver_name)

%p
= f.label :content
= f.text_area :content
= errors_for(f.object, :content)

%p
= f.submit


En fait je vire l'archive, ces fragments suffisent.


RE: [Rails] Problème après rechargement de formulaire avec autocomplétion en cas d'erreur - popayan - 02-11-2011

nickel, merci beaucoup, reste plus qu'a ajouté un message d'erreur adéquat et ca sera parfait


RE: [Rails] Problème après rechargement de formulaire avec autocomplétion en cas d'erreur - Sephi-Chan - 02-11-2011

En fait, tu affiches l'erreur pour l'attribut receiver et ça marche. Smile


RE: [Rails] Problème après rechargement de formulaire avec autocomplétion en cas d'erreur - popayan - 02-11-2011

Tu veux dire quoi par "ça marche"? J'ai un message pour me dire que le champ est vide mais qu'il ne le doit pas, moi j'aimerai ajouter un message pour dire que le nom saisi n'est pas valide.


RE: [Rails] Problème après rechargement de formulaire avec autocomplétion en cas d'erreur - Sephi-Chan - 02-11-2011

Ben, tu ajoutes un validateur sur le receiver au niveau de ton modèle :


class Message < ActiveRecord::Base
belongs_to :author, class_name: "User"
belongs_to :receiver, class_name: "User"

validates_presence_of :author, :receiver, :title, :body
validate :receiver_exists


def receiver_exists
errors[:receiver_id] << :inclusion unless User.exists?(id: receiver_id)
end
end