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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

838閲覧

複製したフォームのデータを保存したい

退会済みユーザー

退会済みユーザー

総合スコア0

Ruby on Rails 5

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2020/11/08 08:33

編集2020/11/09 21:50

前提・実現したいこと

旅行の思い出を投稿するwebアプリを制作しています。
Spotというモデルで一地点ごとに情報をもたせ(address,image,content,title,post_id)、同一のpost_idを持つデータをPostモデルで1つにまとめて投稿するという機能を実装したいのですが、その投稿フォームの処理をつくるところで躓いています。

1つの投稿が持つ情報は、(address,image,content,title)xSpotの数+Postのcontent というふうになります。

投稿フォームは1ページで完結させたいので、Spotのフォームを、最初にレンダリングされる段階では1つのみで、「フォームを追加」ボタンがクリックされるたびに1つずつ増えるようにしたいのですが、それを試したところ、フォームを増やすことはできたのですが、
追加したフォームから受け取ったデータを保存する処理のイメージができず、ここで手が止まってしまっています。

解決法がわかる方がいましたら、よろしくお願いします。

↓投稿詳細ページにはなりますが、こんなイメージです。
Spotの1つのレコードごとに部分テンプレートを作るような感じです。(左のオレンジの部分)
今作っている投稿フォームでは、このSpotの一つ一つのレコードとPostのcontent(右上のグレーの部分)を保存できるようにしたいです。

投稿詳細
投稿フォーム

該当のソースコード

↓posts/new.html.erb

html

1<div class="container"> 2 <h1 class="form-heading">投稿する</h1> 3 <%= form_with model: @post do |f|%> 4 <div class="field"> 5 <%= f.text_area :content, placeholder: "post.content"%><br> 6 <div id="forms"> 7 <div> 8 <%= f.fields_for :spots do |s| %> 9 <%= s.text_field :title, placeholder: "title"%><br> 10 <%= s.text_field :address, placeholder: "address"%><br> 11 <%= s.text_area :content, placeholder: "spot.content"%> 12 <span class="image"> 13 <%= s.file_field :image, accept: 'image/jpeg,image/gif,image/png' %> 14 </span> 15 <% end %> 16 </div> 17 </div> 18 </div> 19 <div class="btn btn-primary" id="add-form">フォームを追加</div> 20 <%= f.submit "投稿", class: "btn btn-primary" %> 21 22 <% end %> 23</div> 24 25<!-- フォームの追加 --> 26<script> 27 document.getElementById("add-form").addEventListener("click", function(){ 28 let forms = document.getElementById("forms"); 29 let clone = forms.firstElementChild.cloneNode(true); 30 31 forms.appendChild(clone); 32 }); 33</script>

↓posts_controller.rb

Ruby

1 def new 2 @post = Post.new 3 @post.spots.build 4 end 5 6 def create 7 @post = current_user.posts.build(post_params) 8 @post.save 9 redirect_to root_path 10 end 11 12def post_params 13 params.require(:post).permit(:content, spots_attributes: [:address, :image, :content, :title]) 14 end

試したこと

Spotのフォームを追加して投稿すると、最後のフォームの値のみ保存されるようです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

説明が少しあやふやな気がするのですが、Spot has many Postsということだと思います。

参考:【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】????

上記でアソシエーションについてきちんと整理しておいたほうが良さそうな気がしました。。。


Railsではたくさんのフォームを作って、データを送信する場合、フォームオブジェクトを使って実装する形になるかと思います。
下記のような形を実装したいのだと思いますが、Rails2かRails3で作られていて解読が非常に難しいです。。。。

参考:https://rails.densan-labs.net/form/relation_register_form.html
※このRails6バージョンがほしい。


個人的におすすめなのは、SpotページにPostフォームを1つ設置して、登録完了した投稿がどんどん下に追加される形です。
例えば浅草(spot_id=3)ページで記事(Post)を書けば、Postモデルのspot_idカラムに3が入るようすると、期待したものが実現できるかと思います。
これの良いところは実装がすごいシンプルで、かつストレスなく利用できるところです。
下記だと追加しかできませんが、編集ボタンをそれぞれの投稿の下につけておけば運用的にも問題ないかと思います。

参考:Railsガイド:JavaScript シンプルな例

投稿2020/11/08 09:11

no1knows

総合スコア3365

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

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

退会済みユーザー

退会済みユーザー

2020/11/08 09:46

すみません説明不足でした…。 この場合、Post has many Spotsなはずです モックアップを追加したので、もしお暇があれば確認お願いします
no1knows

2020/11/08 11:37

失礼しました。 日本旅行の思い出(post)に、訪問先(spot)、例えば札幌・渋谷・富士山があるということですね。 アプローチ方法を1つ忘れていました。 DHHさん(Rails作者)が無くしたいとつぶやいていたaccepts_nested_attributes_forで実現可能かもしれません。⇒こちらなら比較的実装がスムーズかも
退会済みユーザー

退会済みユーザー

2020/11/09 21:49

すみません。時間が取れず返信が遅れました。 accepts_nested_attributes_forは使っていて、 現状、「spotが1つであれば問題なく保存できるが、spot部分のフォームを複製した時、一番下のフォームに入力された値しか、保存されない」という状態になっていて、複製したフォームの値すべてを保存できるようにしたいというのがこの質問の趣旨です。
no1knows

2020/11/10 01:47

> accepts_nested_attributes_forは使っていて、 であればそのソースか使っている旨を書かないと、回答する人が無駄な手間が増えるばかりです。 (まぁ、今は僕なんですが・・・) そもそもaccepts_nested_attributes_forは好きじゃないので、あまり知見がないのですが、切り分けするなら JavaScriptを外して、フォームを複数にして、きちんと保存できるか確認する。 ⇒これできちんと保存できるならaccepts_nested_attributes_forの設定は正しいことがわかるので、あとはJavaScriptを確認。 ⇒きちんと保存されないならそもそもaccepts_nested_attributes_forの設定がおかしいのでそこを修正。 参考までにaccepts_nested_attributes_for使うならcocoonを使うのが定番かと思います。
退会済みユーザー

退会済みユーザー

2020/11/10 03:27

質問の仕方に拙い部分があり、失礼しました…。 原因をどう探ればいいのかもわかっていない状態でしたので、一度試してみようと思います。 質問に対するご指摘、解決法ともに参考にさせて頂きます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問