質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

1回答

2047閲覧

[Rails]ActionController::InvalidAuthenticityToken in PostControllerというエラーが表示されて解決できないです、どなたか解決案があればど

suirunakamura

総合スコア16

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/08/09 06:56

編集2020/08/12 03:23

前回の質問で、Routing errorを質問させていただいたのですがこのエラーについて調べていると、以下の記事を見つけ参考にしました。
リンク内容
上記リンクURL: https://qiita.com/makoto15/items/88fde979fac6c4686680
この記事では、routes.rbに 『post 'post/new' => 'post#new'』のようにnewアクションにPOSTメソッドを指定してあげることで解決できるだろうと記述されていました。
自分の現在のpostコントローラーファイルはこのようになっています。

Rails.application.routes.draw do # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html root to: "top#index" post 'post/new' => 'post#new' resources :post end

すると、このようなエラー文が表示されました。

ActionController::InvalidAuthenticityToken in PostController#new ActionController::InvalidAuthenticityToken Extracted source (around line #215): def handle_unverified_request raise ActionController::InvalidAuthenticityToken end end end

このエラー文の解決について知っている方がいればご教授して欲しいです。どうかよろしくお願いします、、
今回のようなエラーは見たことがないので、調べてみます。

『追記』

winterbounさん、maisumakunさんに、form_withをご教示いただきviewのフォームを下記のように変更修正しました。

viewファイル

new.html.haml

1= render partial: 'shared/header' 2%body 3 .container 4 .row 5 .col-md-8.col-md-offset-2 6 %h2 ブログ記事投稿・編集 7 = form_with local:true, model: @articles do |f| 8 .form-date.form-group 9 .blog-name 10 %label.blog-label 日付 11 = f.date_field :dating, class: "input-time", name: "post_date", size: "20", placeholder: "日付を入力してください", style: "font-weight: bold;" 12 .form-title.form-group 13 .blog-name 14 %label.blog-label タイトル 15 = f.text_field :title, class: "input-title", name: "title", placeholder:"タイトルを入力してください。", style: "font-weight: bold;" 16 .form-letter.form-group 17 .blog-name 18 %label.blog-label 本文 19 = f.text_area :text, class: "input-control", rows: "15", name: "body", placeholder: "本文を入力してください。", style: "font-weight: bold;" 20 .form-input 21 = f.submit class: "btn btn-primary btn-sm", value: "投稿する" 22

postコントローラーファイル

post_controller.rb

1class PostController < ApplicationController 2 3 class Post 4 def create 5 # ストロングパラメータから精査されたデータだけをインスタンスに格納 6 @articles = Article.new(blogs_params) 7 8 # インスタンスに保存成功した場合の処理 9 if @articles.save 10 flash[:success] = "ユーザーを登録しました" 11 # redirect_to @articles 12 13 # インスタンスの保存に失敗した場合の処理 14 else 15 flash[:danger] = "ユーザーの登録に失敗しました" 16 # render :new 17 end 18 end 19 20 private 21 def blogs_params 22 params.require(:articles).permit(:dating, :title, :text) 23 end 24 end 25end

routes.rb

Rails.application.routes.draw do # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html root to: "top#index" resources :posts end

このように変更しました。これで、ブラウザを開くと

リンク内容

uninitialized constant PostsController Did you mean? PostController TopController

上記のエラーが表示。
コントローラ名が、post_controller.rbなので、resources postsだと難しそう?
resources :postに変えて実行すると、

フォームが表示され、投稿ボタンまで押せる!
しかし、次に下記のようなエラーが表示されました。。

リンク内容

Routing Error No route matches [POST] "/post/new" Rails.root: /Users/apple/create/portfolio

これは、また昨日からのposts/post宛てになっていない問題なのでしょうか?
知識が浅く申し訳ありません。エラーの確認と返信お願いします。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

これは get newや get edit の時に(つまり戻りが postやpatchなどデータ書き換えが予想されるとき)に渡されるtokenが送り戻されていないことによるエラーです。
通常は出ません。
なぜ出たかというと、、、、、
元の質問でのやり取りを見ていてはて、、、と思ったのですが、newとcreateの役割を間違えています。
new は 新規に作成するための画面を呼び出すもので get が正しいです。
そのnew.html からデータを受けて新規作成するのが create です。
viewが載っていないのでそれが new.htmlだとして書くと

元質問の def new を def create にし、
def new @blog = Post.new end
として、、、、
ん〜〜〜 formをどう作っているのかな、多分そこに問題がありそう。
<form> で作ってませんか? <%= form_for とか form_with を使わずに。
viewを載せてください。

追記

getでなくデータ書き換え系は<form>でベタに書くのは薦めません。その場合は
<input type="hidden" name="authenticity_token" value="YFzoRZBWitgncRPPJxd0R+YnpKa9WfO4oJM/VzKmj1oD4pouoaGrS6Yi0FSMm0xOBFU9LTtFa4McKhNJxxJM8A==" />
こんなのをformの中に書かなければなりません。初級のやることではないです。
(念の為、valueの値は毎回違います。これをそのままコピペしてもInvalidAuthenticityTokenです)

素直に = form_with @post と書きましょう。(hamlの書き方身についていないから違うかも)
それで InvalidAuthenticityToken は出なくなります。newでなく create へ誘ってくれます。

maisumakun さんも何度も書いていますが、newではなく create にすべきです。
routes.rb でも素直に resources :posts って書きましょう。
意図なく 標準と違うことはしないほうが良いです。初級のすることではありません

投稿2020/08/09 22:56

編集2020/08/11 09:51
winterboum

総合スコア23376

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

suirunakamura

2020/08/11 09:35 編集

返信ありがとうございます!その通りです、、 フォームは、for withを使わずに、formタグを使用しています。 上記のように、viewを作りました。 %body .container .row .col-md-8.col-md-offset-2 %h2 ブログ記事投稿・編集 %form(method="post" ) .form-date.form-group .blog-name %label.blog-label 日付 %input.input-time(name="post_date" size="20" value="" placeholder="日付を入力して下さい。" style="font-weight: bold;" ) .form-title.form-group .blog-name %label.blog-label タイトル %input.input-title(name="title" value="" placeholder="タイトルを入力して下さい。" style="font-weight: bold;" ) .form-letter.form-group .blog-name %label.blog-label 本文 %textarea.input-control(rows="15" name="body" placeholder="本文を入力してください。" style="font-weight: bold;") .form-input %input.btn.btn-primary.btn-sm(type="submit" value="投稿する" )
maisumakun

2020/08/11 09:40 編集

なぜnewへのpostにこだわるのでしょうか? 特に理由がないなら、ルーティングはRails標準のものをそのまま使うほうが合理的です。
suirunakamura

2020/08/11 09:55

ルーティングにresources :postだけを指定すると、 No route matches [POST] "/post/new" というエラーが表示されてしまいます。
maisumakun

2020/08/11 10:03 編集

ですから、/post/newではなく/post(こちらにcreateがresourcesでつながる)へPOSTしてください。
maisumakun

2020/08/11 10:05

(/post/newへPOSTされてしまうのも、フォームヘルパーを使わずに自分で<form>を作っているのが一因です)
suirunakamura

2020/08/11 10:13

viewのformタグの引数の、method postの記述を消したら、エラーが解決しました。愚問を申し訳ありませんでした。 しかし、このフォームから持ってきた情報を予め作っていたデータベースに入りません。これは、viewのinputタグの方に、モデルの指定をすれば、よろしいのですか?愚問ばかり申し訳ありませんが、ご教示していただけたら幸いです!
maisumakun

2020/08/11 10:16 編集

> viewのformタグの引数の、method postの記述を消したら、エラーが解決しました。愚問を申し訳ありませんでした。 全く解決していません(それは「たまたまエラーが出なくなっただけ」といいます)。そうしたら、そのフォームは「おなじページへGET送信する」ということになるので、「ページを再表示する」だけの機能になってしまいます。 素直にform_withを使いましょう。
winterboum

2020/08/11 10:17

resources :post じゃないです resources :posts 複数形
suirunakamura

2020/08/11 10:30

ターミナルの記述を確認してみると、 Started GET "/post/new" for ::1 at 2020-08-11 19:06:36 +0900 Processing by PostController#new as HTML Rendering post/new.html.haml within layouts/application Rendered shared/_header.html.haml (Duration: 0.1ms | Allocations: 11) Rendered post/new.html.haml within layouts/application (Duration: 15.4ms | Allocations: 8790) Completed 200 OK in 25ms (Views: 22.6ms | ActiveRecord: 0.0ms | Allocations: 12331) Started GET "/post/new?post_date=12%E6%9C%8812%E6%97%A5&title=mysql%E3%81%AE%E3%82%A8%E3%83%A9%E3%83%BC%E6%96%87%E3%81%8C%E8%A7%A3%E6%B1%BA%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%81%E3%80%81&body=aa" for ::1 at 2020-08-11 19:06:49 +0900 Processing by PostController#new as HTML Parameters: {"post_date"=>"12月12日", "title"=>"mysqlのエラー文が解決できません、、", "body"=>"aa"} Rendering post/new.html.haml within layouts/application Rendered shared/_header.html.haml (Duration: 0.1ms | Allocations: 11) Rendered post/new.html.haml within layouts/application (Duration: 0.5ms | Allocations: 94) Completed 200 OK in 10ms (Views: 8.2ms | ActiveRecord: 0.0ms | Allocations: 2888 と表示されていたので、データは取れていたのかと思いました、、
suirunakamura

2020/08/11 10:30

winter bornさん、返信ありがとうございます。試してみます。
maisumakun

2020/08/11 10:31

> データは取れていたのかと思いました、、 流れてはいますが、newのページでは受け取って処理しませんので無意味です。
suirunakamura

2020/08/11 10:33

ルーティングのpostを複数形にすると、No route matches [GET] "/post/new"のエラーが表示されてしまいます。
suirunakamura

2020/08/11 10:33

大人しく、form_withメソッドを使います。申し訳ありません。。
maisumakun

2020/08/11 10:34

複数形にしたときは、URLが/posts/newに変わります。
suirunakamura

2020/08/11 10:39 編集

現在設定しているパスが post/new なので、ルーティングをpostsにする場合は、パス自体を変更しなければいけないのではないのではないのでしょうか?
maisumakun

2020/08/11 10:39

> 現在設定しているパスが post/new なので その手動設定自体が不要と、何度も何度もコメントしているのですが…
winterboum

2020/08/11 10:44

素直に form_with した時の 作りなおした view を載せましょう
suirunakamura

2020/08/11 23:05

> 素直に form_with した時の 作りなおした view を載せましょう わかりました。
suirunakamura

2020/08/11 23:08

> その手動設定自体が不要と、何度も何度もコメントしているのですが… すみません、ではURLは複数形にせずに、postのURLのままで変更は不要ということでよろしいですか? 愚問で申し訳ありません。
maisumakun

2020/08/11 23:35 編集

> すみません、ではURLは複数形にせずに、postのURLのままで変更は不要ということでよろしいですか? 愚問で申し訳ありません。 違います。resources :postsでできた、「POST /posts」宛てにPOSTしてください。form_withを使えば、その指定すら明示的に行わなくても勝手につないでくれます。
maisumakun

2020/08/11 23:35

Railsの世界には、「Railsが用意してくれた枠組みを利用する」という意味の「レールに乗る」という言葉があります。 suirunakamuraさんがやっていることは、「たまたまレールから脱線したところで復旧しようとせず、自分でレールを別に敷く」という茨の道へ突き進もうとしている状態です。 Railsの利便性を投げ捨てたいという意思があるのなら別ですが、そうすべき状況でないのであれば、「Railsの作法に従った形にコードを修正する」ほうが、圧倒的にやりやすいです。
suirunakamura

2020/08/12 00:48

> 違います。resources :postsでできた、「POST /posts」宛てにPOSTしてください。form_withを使えば、その指定すら明示的に行わなくても勝手につないでくれます。 そういうことですね!本当に理解がなく申し訳ありません。わかりました。やってみます!
suirunakamura

2020/08/12 00:52

> Railsの世界には、「Railsが用意してくれた枠組みを利用する」という意味の「レールに乗る」という言葉があります。 suirunakamuraさんがやっていることは、「たまたまレールから脱線したところで復旧しようとせず、自分でレールを別に敷く」という茨の道へ突き進もうとしている状態です。 Railsの利便性を投げ捨てたいという意思があるのなら別ですが、そうすべき状況でないのであれば、「Railsの作法に従った形にコードを修正する」ほうが、圧倒的にやりやすいです。 わかりやすく説明していただきありがとうございます。本当に知見が浅く恐縮です。
suirunakamura

2020/08/12 03:05

> getでなくデータ書き換え系は<form>でベタに書くのは薦めません。その場合は <input type="hidden" name="authenticity_token" value="YFzoRZBWitgncRPPJxd0R+YnpKa9WfO4oJM/VzKmj1oD4pouoaGrS6Yi0FSMm0xOBFU9LTtFa4McKhNJxxJM8A==" /> こんなのをformの中に書かなければなりません。初級のやることではないです。 (念の為、valueの値は毎回違います。これをそのままコピペしてもInvalidAuthenticityTokenです) 素直に = form_with @post と書きましょう。(hamlの書き方身についていないから違うかも) それで InvalidAuthenticityToken は出なくなります。newでなく create へ誘ってくれます。 maisumakun さんも何度も書いていますが、newではなく create にすべきです。 routes.rb でも素直に resources :posts って書きましょう。 意図なく 標準と違うことはしないほうが良いです。初級のすることではありません winterbounさん、返信遅れすみません。返信ありがとうございます!はい。winterbounさん、maisumakunさんのおっしゃる通り、form_withを使用しました。コードが長くなるので、最初の文に『追記』として載せておきます。親切にご教授ありがとうございます!
winterboum

2020/08/12 03:07

最初の文 ってどれ?
suirunakamura

2020/08/12 03:08

今、コードを挿入してます。
suirunakamura

2020/08/12 03:24

遅くなりすみません、追記を加えました。エラーの確認と解決案・どうかよろしくお願いします。
maisumakun

2020/08/12 03:52

> コントローラ名が、post_controller.rbなので コントローラー名もPostsControllerにそろえてください。
suirunakamura

2020/08/12 04:24

> コントローラー名もPostsControllerにそろえてください。 コントローラ名とviewのフォルダ名をPostsに変更しました! >posts >new.html.haml posts_controller.rb class PostsController < ApplicationController class Posts
maisumakun

2020/08/12 04:28

そもそも論ですが、なぜPostsControllerなのにArticleを扱っているのですか?
suirunakamura

2020/08/12 04:41

記事についてのテーブルを作成しようと思ったからです。
maisumakun

2020/08/12 04:42

では、ArticlesControllerで扱うのが適切です。
winterboum

2020/08/12 04:42

しかも @articles 復数だし。 このviewを呼び出すcontrollerは何で、何を定義してますか?
maisumakun

2020/08/12 04:43

いったんこれは置いておいて、いちからRailsチュートリアルに沿って作ってみるほうがいいかもしれません。
suirunakamura

2020/08/12 04:44

確かに、そうですね。考えてみれば、postもarticleも同じ記事投稿の機能実装のために作成したのに、別の名前にした意味が、、
suirunakamura

2020/08/12 04:45

postscontrollerで作成していて、postsフォルダのnew. html.hamlでviewを作っています。
winterboum

2020/08/12 04:48

どうします。作りなおすならそちらを進めて、詰まったら改めて質問していただければ。 それから 「postscontrollerで作成していて、postsフォルダのnew. html.hamlでviewを作っています」では情報ないです、 こういう時はcontroller、viewの codeを載せてください。
suirunakamura

2020/08/12 04:52

posts_controller.rb class PostsController < ApplicationController class Posts def create # ストロングパラメータから精査されたデータだけをインスタンスに格納 @articles = Article.new(blogs_params) # インスタンスに保存成功した場合の処理 if @articles.save flash[:success] = "ユーザーを登録しました" # redirect_to @articles # インスタンスの保存に失敗した場合の処理 else flash[:danger] = "ユーザーの登録に失敗しました" # render :new end end private def blogs_params params.require(:articles).permit(:dating, :title, :text) end end end posts/new.html.haml = render partial: 'shared/header' %body .container .row .col-md-8.col-md-offset-2 %h2 ブログ記事投稿・編集 = form_with local:true, model: @articles do |f| .form-date.form-group .blog-name %label.blog-label 日付 = f.date_field :dating, class: "input-time", name: "post_date", size: "20", placeholder: "日付を入力してください", style: "font-weight: bold;" .form-title.form-group .blog-name %label.blog-label タイトル = f.text_field :title, class: "input-title", name: "title", placeholder:"タイトルを入力してください。", style: "font-weight: bold;" .form-letter.form-group .blog-name %label.blog-label 本文 = f.text_area :text, class: "input-control", rows: "15", name: "body", placeholder: "本文を入力してください。", style: "font-weight: bold;" .form-input = f.submit class: "btn btn-primary btn-sm", value: "投稿する" になっています。
suirunakamura

2020/08/12 04:56

今回のエラーno routes matchesnの原因は、データベースのテーブルとモデル名がArticleでコントローラがPostで一致しないことが原因で間違いないのでしょうか? その場合、モデルかコントローラどちらかを、片方に合わせるように、作成すればよろしいのでは無いのでしょうか? 例えば、新しいコントローラでArticlesコントローラを作成して、ファイルの中のコードはコピペで、、
maisumakun

2020/08/12 04:59

> 今回のエラーno routes matchesnの原因は、データベースのテーブルとモデル名がArticleでコントローラがPostで一致しないことが原因で間違いないのでしょうか? その場合、モデルかコントローラどちらかを、片方に合わせるように、作成すればよろしいのでは無いのでしょうか? 他にも間違いがあることが考えられます(実際、@articlesという変数名も適切なものではありません)。
suirunakamura

2020/08/12 05:06

インスタンス変数の@articleは、sを取り除き、単数形に直しました。 インスタンス変数は、作成したモデル名と同じ名前を定義することが必須なのでしょうか?
suirunakamura

2020/08/12 07:43

No route matches [POST] "/posts/new"とエラーが出ているということは、フォームに入力した情報も渡せていなさそうですか?
maisumakun

2020/08/12 07:44

> フォームに入力した情報も渡せていなさそうですか? それとは全く別系統の問題です。POST先が違います。
suirunakamura

2020/08/12 07:48

データの送っている先が、違うものを指定してしまっているということでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問