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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

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

Q&A

解決済

1回答

656閲覧

Rails6 accepts_nested_attributes_forにより、ネストした関連先のテーブルもまとめて保存したい。

YousukeTanaka

総合スコア79

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

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

0グッド

0クリップ

投稿2020/01/27 06:40

編集2020/01/31 07:28

実現したいこと

Userテーブルと1対1の関係があるStudentテーブルがあり、どちらか一方が更新されれば、もう一方も更新されるようにしたい。
イメージ説明

問題点

以下、2点の問題が発生しています。
①Studentの入力部分が非表示になっている。
②以下のエラーが発生している。

そのために、Controller部分を確認し、フィードバックをいただけないでしょうか?

イメージ説明

Modelの記載

親:User.rb

class User < ApplicationRecord has_one :student, dependent: :destroy accepts_nested_attributes_for :student end

子:Student.rb

class Student < ApplicationRecord belongs_to :user, optional: true, inverse_of: :student end

Table構造

Usersテーブル create_table "users", force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "fullname" t.integer "unread", default: 0 t.bigint "global_user_id" t.bigint "school_person_in_charge_id" t.bigint "student_id" t.index ["email"], name: "index_users_on_email", unique: true t.index ["global_user_id"], name: "index_users_on_global_user_id" t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true t.index ["school_person_in_charge_id"], name: "index_users_on_school_person_in_charge_id" t.index ["student_id"], name: "index_users_on_student_id" end

studentsテーブル

create_table "students", force: :cascade do |t| t.string "nickname" t.date "birth" t.integer "gender" t.string "image" t.text "comment" t.bigint "user_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["user_id"], name: "index_students_on_user_id" end

Controllerの記載

Profiles_controller.rb

class StudentAdmin::ProfilesController < StudentAdmin::StudentsController before_action :authenticate_user! def edit @user = current_user end def profile_update if current_user.student.nil? current_user.create_student!(profile_params) else current_user.student.update(profile_params) end redirect_to user_profile_path(current_user) end private def profile_params params.require(:user).permit(:fullname, :email, :avatar, student_attributes: [:id, :nickname, :birth, :gender, :comment, :user_id]) end end

Form(HTML)の記載

<%= simple_form_for(user, url: user_profile_update_path(user), method: :put, html:{ multipart: true }) do |f| %> <%= f.error_notification %> <%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %> //ここは、親テーブルのhtml要素 <div class="form-group row"> <label for="inputEmail3" class="col-sm-3 col-form-label">Fullname</label> <div class="col-sm-9"> <%= f.input :fullname, label: false, input_html: { value: current_user.fullname, class: "form-control" }, required: true, autofocus:true %> </div> </div> <div class="form-group row"> <label for="inputEmail3" class="col-sm-3 col-form-label">Email</label> <div class="col-sm-9"> <%= f.input :email, label: false, input_html: { value: current_user.email, class: "form-control"}, required: true, autofocus: true %> </div> </div> <div class="form-group row"> <label for="filenam" class="col-sm-3 col-form-label">Photo</label> <div class="col-sm-9"> <div class="row"> <div class="col-md-8"> <div class="text-left" style="padding-bottom: 1rem;"> <% if user.avatar.attached? %> <%= image_tag user.avatar.variant(resize: "200x200"), class: "rounded img-thumbnail" %> <% end %> </div> <div class="input-group"> <div class="input-group-prepend"> <div class="input-group-text" id="select_file_button">Click!</div> </div> <!-- <input id="filename" readonly type="text" value="""> --> <input id="filename" readonly type="text" value="<%= user.avatar.filename if user.avatar.attached? %>" class="form-control" aria-describedby="select_file_button"> <%= f.input :avatar, label: false, as: :file, required: true, input_html: { class: "form-control-file", id:'file_button'}, wrapper: false %> </div> </div> </div> </div> </div> //以下は、子テーブルのhtml要素 <%= f.simple_fields_for :student, @user.student do |p| %> <div class="form-group row"> <label for="inputPassword3" class="col-sm-3 col-form-label">Nickname</label> <div class="col-sm-9"> <%= p.input :nickname, label: false, required: true, autofocus: true, input_html: { class: "form-control"}, wrapper: false, label_html: { class: "label" } %> </div> </div> <div class="form-group row"> <label for="inputPassword3" class="col-sm-3 col-form-label">Birthday</label> <div class="col-sm-9 d-flex flex-row justify-content-between align-items-center"> <%= p.input :birth, label: false, required: true, input_html: { class: "form-control mx-1"}, wrapper: false, as: :date, start_year: Date.today.year - 60, end_year: Date.today.year - 6, discard_day: true, order: [:month, :year] %> </div> </div> <fieldset class="form-group"> <div class="row"> <legend class="col-form-label col-sm-3 pt-0">Gender</legend> <div class="col-sm-9"> <div class="form-check"> <%= p.input :gender, :label => false, :collection => [[0, 'Male'], [1, 'Female']], :label_method => :last, :value_method => :first, :item_wrapper_class => 'inline', :input_html => { class: "form-check-input" }, :as => :radio_buttons %> </div> </div> </div> </fieldset> <div class="form-group row"> <label for="inputPassword3" class="col-sm-3 col-form-label">Self Introduction</label> <div class="col-sm-9"> <%= p.input :comment, label: false, as: :text, required: true, autofocus: true, input_html: { class: "form-control", rows: 7}, wrapper: false, label_html: { class: "label" } %> </div> </div> <% end %> <div class="form-group row"> <label for="inputPassword3" class="col-sm-3 col-form-label"></label> <div class="col-sm-9 text-center"> <%= f.button :submit, (user.new_record? ? "Record" : "Update"), class: "btn btn-primary" %> </div> </div> <% end %>

上記の結果は、親テーブルの表示はできますが、子テーブルの表示ができない状況です。ただし、viewsの

<%= f.simple_fields_for :student do |p| %>

のstudentを"students"に変えた場合は、子要素の部分が表示されます。ただし、保存ができません。私自身は、controllerの書き方に問題があるのではないかと考えていますが、色々と試してみましたが、解決に至っていません。お知恵をお貸しいただけると幸いです。

補足情報

ruby 2.5.7p206
Rails 6.0.2.1
Deviseというgemを使って、User管理を行なっています。
form は、simple_formというgemを使っています。

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

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

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

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

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

winterboum

2020/01/29 21:33

viewが長いので、読み解くのが面倒でパスしちゃってました。 親テーブルの表示 は どの部分 子テーブルの表示 は どの部分 子テーブルの表示ができない とは、その部分が全く無いのか、データが無いのか を教えてください User、Student の table構成(migration) を載せてください
YousukeTanaka

2020/01/31 07:13

winterboum様。コメントありがとうございます。ご指摘に従い、情報を追加いたしました。 >子テーブルの表示ができない とは、その部分が全く無いのか、データが無いのか 子テーブルの要素の表示が全てできていない状態となります。 お手を煩わせてしまい、申し訳ございませんが、ご助言により方向性が見えてくれば嬉しい限りです。よろしくお願いいたします。
winterboum

2020/01/31 07:19 編集

子テーブルの要素の表示が全てできていない と言うのは、表示すべきの場所にその枠はあるのだがデータがない という意味ですか? ああ、要素とはhtml要素かわかりました form全体は消しちゃったんですね。 それ復活してください。
YousukeTanaka

2020/01/31 07:34

承知しました。元のコードに戻しました。もし、今回の解決が難しい場合、他の解決も模索したいと思っています。その場合、そもそも、accepts_nested_attributes_forの使用そのものにも疑問を持ちながら、使っており、こちらもご相談できればとおもています。過去の投稿にもありますし、googleでも調べるとあまり推奨されているコードではないと認識しております。これに変わるやり方も調べたのですが、複雑で理解できず、accepts_nested_attributes_forを使っておりました。もし、参考になるドキュメントがございましたら、教えていただけないでしょうか?
guest

回答1

0

ベストアンサー

画像のエラーは
current_user.create_student!(profile_params)
としているので、studentのパラメータとしてのpermitに userのものであるfullname が指定されているからです。
どうするのかな、、
current_user.create_student!(profile_params[:student_attributes])
で試してみてください。

親と子を一緒に扱う場合は大抵は
@user = User.find(params[:id])としておいて
@user.update(profile_params) としますが、それではまずいことが起きる?

子table部分の件ですが、
simple_*は使ったことがないので手探りですが、:studentsにして表示ができるが保存が出来ない、というところのlogをみると何か判るかもしれません。
単に、上の問題であったのかもしれませんし

投稿2020/01/31 07:35

winterboum

総合スコア23364

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

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

YousukeTanaka

2020/01/31 07:36

ご回答感謝しております。早速試してみます。
YousukeTanaka

2020/02/12 13:30

返信が遅れました。has_oneのやり方を学習しました。おっしゃったやり方を理解するのに時間がかかりましたが、表示がされました。ご助言感謝しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問