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

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

ただいまの
回答率

87.94%

[rails]accepts_nested_attributes_for使った入力フォームの情報が保存できない

解決済

回答 1

投稿

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

score 5

現在個人でWEBサービスを開発している者です。
◾️やりたいこと
railsで、accepts_nested_attributes_forを使って子モデルも一緒に保存したい
◾️課題
入力フォームに値を入れてsubmitしてもDBに値が保存されない
(エラー等が起きるわけでもなく、画面もしない)

イメージ説明

お手数ですが、有識者の皆様のお力添えいただけますと幸いです。
サイト等みながら色々と試してみた関係で、
不要なコードやDB項目が含まれているかもしれませんがご了承ください。
また、不足している情報があればお出ししますのでご教示ください。

◾️テーブル一覧
概要:ユーザー(user)が、プラン名(plan)を投稿します。同時にnested modelのプラン詳細(posts)を登録するというイメージです。
例:ユーザ1(user)が箱根1泊旅行(plan)と同時に時間等(posts)を登録
users:
("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "email" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, "image_name" varchar, "password_digest" varchar);
plans:
("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "plan_name" varchar, "user_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);

posts:
("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "content" text, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, "user_id" integer, "plan_id" integer, "plan_date" varchar, "arrival_time" varchar, "place_image" varchar, "place_name" varchar);

◾️ソース一覧
★plan.rb

class Plan < ApplicationRecord
      validates :user_id, {presence: true}

      belongs_to :user
      has_many :posts
      accepts_nested_attributes_for :posts

end

★post.rb

class Post < ApplicationRecord
  validates :user_id, {presence: true}
  belongs_to :plan

  def user
    return User.find_by(id: self.user_id)
  end

end

★user.rb

class User < ApplicationRecord
    has_secure_password

    validates :email,{uniqueness: true}
    validates :password,{presence: true}

    has_many :plans
    has_many :posts

    def posts
      return Post.where(user_id: self.id)
    end
end

★/app/views/plans/new.html.erb

  <div class="main posts-new">
    <div class="container">
      <h1 class="form-heading">プランを作成する</h1>

    <%= form_for @plan,:url => {:controller => :plans ,:action => :create} do |f| %>
    <div class="form">
    <div class="form-body">
    <div class="field">
      <%= f.label :プラン名 %><br>
      <%= f.text_field :plan_name %>
    </div>
    <div class="field">
      <%= f.label :posts, "プラン詳細" %><br />
      <%= f.fields_for :posts do |posts_form| %>
        <%= posts_form.hidden_field :user_id, value: @current_user.id %>
        <%= posts_form.label  :日付 %>
        <%= posts_form.date_field :plan_date %><br />
        <%= posts_form.label :到着時間 %>
        <%= posts_form.time_field :arrival_time %><br />
        <%= posts_form.label :地名 %>
        <%= posts_form.text_field :place_name %><br />
        <%= posts_form.label :やること %>
        <%= posts_form.text_field :content %><br />
      <% end %>
      </div>
      <%= f.submit "作成" %>
      </div>
    <% end %>
    </div>

★/app/controllers/plans_controller.rb

class PlansController < ApplicationController
  before_action :authenticate_user

  def create
    @plan = Plan.create(plan_params)
    if @plan.save
      flash[:success] = "投稿が完了しました!"
      redirect_to("/posts/index")
    else
      flash.now[:alert] = "投稿が失敗しました。"
      #render
    end
  end


  def new
    @plan = Plan.new
    @plan.posts.build
  end



  private
  def plan_params
        params.require(:plan).permit(
          :plan_name,
          :prefecture_id,
          posts_attributes: [:id, :plan_id, :user_id, :plan_date, :arrival_time, :place_name, :place_image, :content, :_destroy]
        ).merge(user_id: @current_user.id)
  end

end

★route.rb

Rails.application.routes.draw do

  post 'users/create' => 'users#create'
  get "signup" => "users#new"
  get 'users/index' => 'users#index'
  get 'users/:id' => 'users#show'
  get 'users/:id/edit' => 'users#edit'
  get 'users/:id/likes' => 'users#likes'
  post 'users/:id/update' => 'users#update'
  post 'users/:id/destroy' => 'users#destroy'
  get 'login' => 'users#login_form'
  post 'login' => 'users#login'
  post 'logout' => 'users#logout'

  get 'posts/index' => 'posts#index'
  get 'posts/new' => 'posts#new'
  get 'posts/:id' => 'posts#show'
  post 'posts/create' => 'posts#create'
  get 'posts/:id/edit' => 'posts#edit'
  post 'posts/:id/update' => 'posts#update'
  post 'posts/:id/destroy' => 'posts#destroy'

  get 'plans/new' => 'plans#new'
  post 'plans/create' => 'plans#create'

  get '/' => 'home#top'
  get '/about' => 'home#about'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

◾️参考にしたサイト1
◾️参考にしたサイト2

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • gawao

    2020/01/18 21:38

    shinoharatさん
    色々とご確認ありがとうございます!!!泣 先に回答できるものからお答えします!!!!
    ◾️1つ目のコメント
    @plan = Plan.new(plan_params)を試しましたが変わらずです。

    ◾️2つ目のコメント
    【1】【2】→申し訳ございませんが確認方法が分からずなのでもう少々お時間いただけますでしょうか、、

    【3】
    >・Plan は保存されるが Posts が保存されない
    >・Plan も Posts も保存されない
    >のどちらでしょうか?
    →どちらもです。

    【4】
    「画面遷移もしない」の書き間違いです、、、

    >・入力画面が再度表示される
    →正しいです。
    >・"投稿が失敗しました。" の flash メッセージが表示される
    →flashも表示されません
    >・しかし、バリデーションエラーは表示されない
    →正しいです。

    【5】
    「新規作成時に DB に保存されない」というお悩みで間違いないですよね?(「新規はできるけど更新はできない」という話ではないですよね?)
    →新規作成時にDBに保存されないで正しいです!

    ◾️3つ目のコメント
    追記してみましたが、バリデーションエラーも表示されません、、、

    キャンセル

  • gawao

    2020/01/18 21:54

    追記です。
    ◾️3つ目のコメント
    plans_controller.rbで、render("plans/index")を追記すると、下記のメッセージが表示されました!!
    「Posts plan must exist」
    相変わらずflashメッセージは表示されません、、

    キャンセル

  • gawao

    2020/01/18 22:02

    保存できました!!!
    optional: trueをbelongs_toに付けたら保存はできたのですが、本来このような書き方は良いのですかね??
    belongs_to :user, optional: true
    belongs_to :plan, optional: true

    キャンセル

回答 1

checkベストアンサー

0

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/01/20 08:39

    共有ありがとうございます。
    あまり使うべきメソッドではないのですかね〜、、?
    まだまだ勉強が必要です、、

    いずれにしても、様々な助言ありがとうございました、大変助かりました!

    キャンセル

  • 2020/01/20 09:24

    僕は初学者なのでなんとも言えないですが…
    どうしてもじゃなければ積極的に採用しない方向にしたいと思います。
    将来的になくなる≒バージョン上げる際の負債になりそうといったコメントも頷けるので…

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る