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

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

ただいまの
回答率

90.11%

【Rails5】form_withを使ったcreateアクションがうまくいきません。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 959

taruya

score 6

初めて質問させて頂きます!

form_withを使って投稿詳細ページにレビューを入力するフォームを作ったのですが、createアクションがうまく行きません。

エラーログを見るとコントローラにパラメータは送信されているようなのですが、@review.saveの時にROLLBACKが起きている状態で、どこで問題が起きているかが分からず質問させて頂きました。

なお、planモデルとreviewモデル、及びuserモデルとreviewモデルにはそれぞれ一対多のアソシエーションを定義しており、reviewsテーブルには以下のカラムを挿入することを想定しています。

rate
review
user_id
post_id

以上、どなたかよろしくお願いします。

/reviews/_form.html.erb

<%= form_with(model: [ @plan, Review.new])  do |form| %>

  <div class="field">
    <%= form.label :rate %>
    <%= form.number_field :rate %>
  </div>

  <div class="field">
    <%= form.label :review %>
    <%= form.text_field :review %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>

<% end %>

routes.rb

ails.application.routes.draw do

  devise_for :users
  resources :examples
  resources :users, only: [:show]
  resources :plans do
      resources :reviews, only: [:create, :update, :delete]
      #/plans/:plan_id/reviews(.:format)
      #Memo: 遷移先をplan_reviews_pathで指定
  end
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  root to: 'plans#index'
  # resource :mypage
end


reviews_controller

class ReviewsController < ApplicationController
  before_action :set_review, only: [:create, :edit, :update, :destroy]

  (略)

  # POST /reviews
  def create
      @plan = Plan.find(params[:plan_id])
    @review = Review.new(review_params)
        @review.user_id = current_user.id
    respond_to do |format|
      if @review.save
        format.html { redirect_to "plans/show", notice: 'レビューしました' }
      else
        format.html { render "plans/show" }
      end
    end
  end

  (略)

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_review
      @review = Review.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def review_params
      params.require(:review).permit(:rate, :review).merge(user_id: current_user.id)
    end
end

エラーログ

Started POST "/plans/10/reviews" for 10.0.2.2 at 2018-08-04 20:34:08 +0900
Cannot render console from 10.0.2.2! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ReviewsController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"9pAqwwnPFKKynkPfR1EyIcRP6SEiSEoXFdxpIj/Fxmo2sVG1Kg9IMw2CIMUlGXImPvLO7JX+97w8q5lOSDjpeQ==", "review"=>{"rate"=>"5", "review"=>"tmp"}, "commit"=>"Create Review", "plan_id"=>"10"}
  Plan Load (0.3ms)  SELECT  `plans`.* FROM `plans` WHERE `plans`.`id` = 10 LIMIT 1
  ↳ app/controllers/reviews_controller.rb:27
  User Load (0.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
  ↳ app/controllers/reviews_controller.rb:73
   (0.1ms)  BEGIN
  ↳ app/controllers/reviews_controller.rb:31
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  ↳ app/controllers/reviews_controller.rb:31
   (0.5ms)  ROLLBACK
  ↳ app/controllers/reviews_controller.rb:31
  Rendering plans/show.html.erb within layouts/application
  Rendered reviews/_form.html.erb (4.2ms)
  Review Load (0.3ms)  SELECT `reviews`.* FROM `reviews` WHERE `reviews`.`plan_id` = 10
  ↳ app/views/plans/show.html.erb:42
  Rendered plans/show.html.erb within layouts/application (41.7ms)
Completed 200 OK in 456ms (Views: 431.8ms | ActiveRecord: 1.9ms)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • takahashim

    2018/08/04 23:15

    post_idがコードに出てきてない気がするんですが、これは不要なんでしょうか? reviewモデルのコードも載せていただいた方が確実かもしれません。

    キャンセル

  • taruya

    2018/08/05 00:25

    takahashimさん、レスポンスを頂きありがとうございます!post_idではなくplan_idでした。

    キャンセル

回答 1

checkベストアンサー

+3

これだけだと、すぐに原因が分からないので、原因の切り分けをしたいです。
そのために、保存処理がそもそも動くのか確認したいですね。
bin/rails consoleで、以下のコードを実行したらどうなりますか?
saveではなく、save!を使う事でエラーがあれば例外が発生し、もう少し具体的なエラーが分かるかもしれません。
※userとplanはレコードがあるものとします

review_params = {
  rate:5, review: "tmp"
}

user = User.first
plan = user.plans.first

review = plan.reviews.new(review_params)
review.user_id = user.id
review.save!

これでエラーが起きずに保存されたらform_withのほうに何か原因があるのかもしれません。
form_withで1つ気になる事というと、
自分がform_with使うときは、オプションでlocal: trueを必ず指定しています。
詳細は忘れましたが、これを付けないとうまく動かない場合があって、それで指定するようにした記憶があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/05 00:23

    ご回答ありがとうございます!
    save!に変えて試す事でvalidation errorがthrowされ、plan_idが渡されていない事が分かりました。そこでreviewsコントローラのcreate_paramsに以下のように書き加えることで無事解決できました。

    .merge(user_id: current_user.id, plan_id: params[:plan_id])

    エラー解決時の考え方やその過程・手法まで丁寧に説明して頂き、とても勉強になりました!ありがとうございます!

    キャンセル

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

  • ただいまの回答率 90.11%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる