[Ruby on Rails] Gestion d'un petit formulaire de commentaires

Le problème exposé dans ce sujet a été résolu.

Salut.

J’ai un peu honte de poster pour ça mais bon ; je me suis lancé récemment sur Ruby on Rails et je cale depuis ce matin sur un petit problème sur lequel je ne pensais sincèrement pas bloquer : je souhaite réaliser un blog « classique » comprenant des articles. Chaque article peut être commenté. Il y a donc un formulaire permettant de poster un commentaire (dont les champs sont Nom, Email, Site, Message) et c’est justement sur ce formulaire que je sèche totalement. Enfin, disons plutôt que j’aimerais faire les choses « proprement » en utilisant ce que Rails propose plutôt que de « setter » tout à la main et je suis tombé notamment sur les « strong parameters », qui d’après ce que j’ai compris, permettent de « cadrer » ce que l’utilisateur entrera comme champs et comme données.

En théorie ça a l’air super, en pratique je me casse les dents dessus et malheureusement la doc ne m’aide pas trop… :/

Mes commentaires se composent donc d’un auteur, qui est une simple chaîne de caractère, d’une date, d’une adresse mail, d’un lien vers un site web, d’un message et sont bien entendu lié à un article. Je précise aussi que j’aimerais si possible que les champs « Auteur », « Email » et « Message » doivent être obligatoirement remplis.

Voici quelques morceaux de mon code.

blog_controller.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class BlogController < ApplicationController
  helper ApplicationHelper

  def index
    @articles = Article.select('id, title, slug, date, image, summary').order('date DESC').paginate(:page => params[:page], :per_page => 5)
  end

  def article
    @article = Article.find(params[:id])
  end
end

comments_controller.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class CommentsController < ApplicationController

  def new
    @comment = Comment.new
  end

  def create
    @comment = Comment.new(comment_params)
    @comment.article_id = params[:id]

    if @comment.save
      # redirection vers l'article
    else
      # erreur
    end
  end

private

  def comment_params
    params.require(:comment).permit(:author, :email, :website, :message)
  end

end
1
2
3
class Comment < ApplicationRecord
  belongs_to :article
end

article.rb

1
2
3
4
5
6
class Article < ApplicationRecord
  self.table_name = "articles"
  belongs_to :category
  belongs_to :user, :foreign_key => "author_id"
  has_many :comments
end

Bref, de manière générale je voudrais savoir s’il y a une manière « propre » de gérer les formulaires (et notamment quand il y a une relation avec un parent) avec Rails ou s’il faut y aller à coup de Object.attribute = params[:form_attribute]

NB : Ma version de Rails est la 5.0.1

Merci d’avance.

1
2
3
4
5
6
7
8
9
def create
  article = Article.find params[:id]
  @comment = article.comments.build comment_params
  if @comment.save
    # ...
  else
    render :new
  end
end

? (ce qui assure dès le départ que l’article qu’on cherche à associer existe)

Je précise aussi que j’aimerais si possible que les champs « Auteur », « Email » et « Message » doivent être obligatoirement remplis.

Rien à voir avec les strong parameters, c’est à toi de mettre les validations voulues dans ton modèle Comment (validates_presence_of :auteur, :email, :message)

Bref, de manière générale je voudrais savoir s’il y a une manière « propre » de gérer les formulaires (et notamment quand il y a une relation avec un parent) avec Rails ou s’il faut y aller à coup de Object.attribute = params[:form_attribute]

Ca dépend, si c’est via le formulaire (= il a le même nom), tu peux whitelister (strong parameters) le paramètre (clé étrangère). Sinon, tu devrais faire le lien via les associations comme décrit en bas du guide dédié à ce sujet.

Effectuer directement l’affectation via params, ce n’est pas vraiment une bonne idée/pratique de manière générale. Il faut vraiment ne pas avoir les objets liés sous la main ni vouloir les charger.

+1 -0

Merci, je suis tombé sur un article qui utilise ce même principe (et ça me parait déjà plus « clair »).

Effectivement j’ai vu qu’on pouvait faire les validations dans le modèle mais il parait que certains préfèrent les faire dans le controlleur, notamment si jamais ils avaient besoin d’utiliser le même modèle dans des « contextes » différents (enfin de toute façon, vu ce que je compte faire, ça ne va vraiment pas me poser de problème à ce niveau là… :P )

Par contre, je bloque encore sur une connerie : ayant fait un contrôleur séparé pour les commentaires, il va bien entendu chercher une vue correspondant au nom de ce contrôleur or j’aimerais que cette partie soit affichée dans la vue article.html.erb. Je sais qu’on peut renvoyer sur une action précise (render ou redirect_to il me semble, (j’ai encore un peu de mal à comprendre la différence entre les deux)), mais il faudra également lui passer les paramètres (mon lien se présente de cette façon : /blog/:id-:slug ) et peu importe ce que je tente, je me tape une erreur (par contre le commentaire est bien enregistré donc ça c’est « presque réglé », manque plus que les diverses validations mais je vais faire comme tu as dit ;) )

Je sais qu’on peut renvoyer sur une action précise (render ou redirect_to il me semble, (j’ai encore un peu de mal à comprendre la différence entre les deux))

render ne renvoie pas sur une action, on ne fait qu’utiliser/rendre le template désigné. redirect_to, c’est une vraie redirection http : tu invites le client à finalement se rendre ailleurs. On trouve généralement un render :new dans l’action create et render :edit dans l’action update mais ce n’est pas pour changer d’action mais simplement pour rendre le template new ou edit quand il y a une erreur de validation pour que l’utilisateur puisse corriger sans rien perdre (voir le §2.2.1 de Layouts and Rendering in Rails)

il faudra également lui passer les paramètres (mon lien se présente de cette façon : /blog/:id-:slug

Sans aller jusqu’à la gem friendly_id, il suffit de redéfinir la méthode to_param dans le modèle correspondant.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte