J'ai une colonne Approuvé dans une base de données qui est fausse par défaut et qui peut devenir vraie en cliquant sur le bouton "Approuver".

Voilà à quoi ressemble ce bouton pour le moment:

<%= link_to('Approve It', @comment_path, method: :update) %>

Mais cela soulève une exception:

Aucun itinéraire ne correspond à [POST] "/ books / 4 / comments / 6

# app/controllers/comments_controller.rb
def update
  @comment = Comment.find(params[:id])
  @comment.approve = true

  redirect_to '/dashboard'
end
# config/routes.rb
resources :books do
  resources :comments
end

Comment puis-je le réparer?

0
xxxecute 23 oct. 2020 à 17:09

3 réponses

Meilleure réponse

Les actions de publication / mise à jour nécessitent des formulaires

Vous utilisez un link_to. C'est bon pour les requêtes GET, mais pas pour les requêtes POST / PATCH / UPDATE. Pour cela, vous devrez utiliser un formulaire en HTML. Heureusement, Rails propose des raccourcis. Vous pouvez utiliser quelque chose comme button_to:

<%= button_to "Approve", { controller: "comments", action: "update" }, remote: false, form: { "id" => @comment.id, "approved" => true } %> 

Cela crée un formulaire pour vous. Qui viendra avec la protection CSRF automatiquement. Vous pouvez styliser le bouton comme vous le souhaitez.

Ou vous pouvez utiliser un lien vers:

 <%= link_to comment_approved_path(@comment), method: :put %>

Mais alors vous auriez besoin de créer une action «approuvée» séparée dans votre contrôleur, et une route séparée pour y accéder.

(Le code ci-dessus n'a pas été testé).

1
BKSpurgeon 23 oct. 2020 à 20:55

link_to doit pointer vers une route / action existante, avec un nom de méthode approprié. Il n'y a pas de méthode HTTP :update.

Pour info: l'action Approuver ne semble pas appartenir à la méthode / action #update. Vous voudrez peut-être l'extraire vers une route distincte comme ceci:

resources :books do
  resources :comments do
    post :approve, on: :member
  end
end

C'est une approche plus idiomatique / courante dans Ruby car #update est généralement préservé pour des mises à jour d'objets plus générales.

Pour cela, vous devrez changer la valeur de l'argument :method en :post et mettre à jour votre route / @ comment_path.

Gestionnaires d'événements Rails-ujs - ce lien peut être utile pour comprendre comment cela fonctionne dans les coulisses.

Espaces de noms et routage des contrôleurs

2
Nikita Fedyashev 24 oct. 2020 à 02:28
#html
<%= link_to "Approve It", book_comment_path(@comment), method: 'put' %>

# app/controllers/comments_controller.rb
def update
  @comment = Comment.find(params[:id])
  @comment.approve = true
  @comment.save 

  redirect_to '/dashboard'
end
1
7urkm3n 23 oct. 2020 à 21:08