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

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

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

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

Ruby on Rails 6

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

647閲覧

多対多で関連付けたモデルのデータ更新を1つのフォームで行う際にオートフィルさせたい

_Taturon_

総合スコア17

Ruby

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

Ruby on Rails 6

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/05/18 09:53

実現したいこと

次のような関連付けを行ったデータの更新(update)を1つのフォーム(memoの更新フォーム)で行いたいです。
その際、memoに関連付けられたsourceモデルのurlを入力フォームにオートフィルさせたいです。
現状でも更新自体はできますが、フォームのurl入力欄が空欄になってしまいます。
ER図

実行環境

・Rails 6.0.0
・ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
・Cloud 9

ソースコード

rb

1class MemosController < ApplicationController 2 3#(中略) 4 5 def new 6 @memo = Memo.new 7 @source = @memo.sources.build 8 end 9 10 def create 11 @memo = Memo.new(memo_params.slice(:word, :content, :synonym, :tag_list)) 12 byebug 13 if @memo.save 14 memo_params[:url].reject(&:blank?).uniq.each do |url| 15 @source = Source.find_or_create_by(url: url) 16 @memo.sources << @source 17 end 18 flash[:notice] = "新しいMemoを作成しました!" 19 redirect_to root_url 20 else 21 flash.now[:alert] = "無効な送信です" 22 render :new 23 end 24 end 25 26#(中略) 27 28 #editとupdateを上手く実装できません 29 def edit 30 @memo = Memo.find(params[:id]) 31 end 32 33 def update 34 @memo = Memo.find(params[:id]) 35 if @memo.update(memo_params) 36 redirect_to root_url 37 flash[:notice] = "Memoを更新しました!" 38 else 39 flash.now[:alert] = "無効な送信です" 40 render :edit 41 end 42 end 43 44 private 45 def memo_params 46 params.require(:memo).permit(:word, :content, :synonym, :tag_list, url: []) 47 end 48end

erb

1<%= form_with model: @memo, local: true do |f| %> 2 <div class="form-group"> 3 <%= f.label :word, "単語" %> 4 <%= f.text_field :word, class: "form-control", %> 5 </div> 6 <div class="form-group"> 7 <%= f.label :synonym, "別名" %> 8 <%= f.text_field :synonym, class: "form-control" %> 9 </div> 10 <div class="field form-group"> 11 <%= f.label :tag_list, "単語" %> 12 <%= text_field_tag 'memo[tag_list]', @memo.tag_list.join(","), class: "form-control" %> 13 </div> 14 <div class="form-group"> 15 <%= f.label :content, "意味" %> 16 <%= f.text_area :content, rows: "10", class: "form-control" %> 17 </div> 18 <div class="form-group"> <!--この部分にmemoと関連付けたurlをオートフィルさせたい--> 19 <%= f.label :url, "単語" %> 20 <%= f.url_field :url, name: "memo[url][]", class: "form-control" %> 21 <%= f.url_field :url, name: "memo[url][]", class: "form-control url-form" %> 22 <%= f.url_field :url, name: "memo[url][]", class: "form-control url-form" %> 23 </div> 24 <div class="form-group"> 25 <%= f.submit yield(:btn_message), class: "btn btn-success btn-lg btn-block" %> 26 </div> 27<% end %>

困っていること

上記内容でeditしようとすると、urlの入力欄に値がオートフィルされません。
原因はeditアクションのインスタンス変数@memoにキーがurlの値が入っていないことだと考えております。
なんとか更新フォームのurl入力欄に@memoと関連付けられたurlをオートフィルさせることは出来ないでしょうか。

試したこと

更新時にオートフィルされるのはeditアクションで作成された@memoに入っているハッシュを元に行われている?と考え、@memoに関連付けたurlを代入しようとしましたが、うまいくいきませんでした。

・関連付けから習得したurlの配列を@sourceに代入し、:urlをキーとして@memoに追加しようとするもエラー

MemoController

1def edit 2 @memo = Memo.find(params[:id]) 3 @source = @memo.sources 4 @memo[:url] = @source 5end

error

1ActiveModel::MissingAttributeError in MemosController#edit 2can't write unknown attribute `url`

・配列として代入したいのだから、挿入先に空の配列を用意してみるもエラー

MemoController

1def edit 2 @memo = Memo.find(params[:id]) 3 @source = @memo.sources 4 @memo[:url][] = @source 5end

error

1NoMethodError in MemosController#edit 2undefined method `[]=' for nil:NilClass

どなたか、ヒントだけでもいいので、ご回答お願い申し上げます。

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

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

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

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

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

winterboum

2020/05/20 08:19

すでに関連付けられているsourceについてのみurlを出したいのでしょうか? それとも、sourceを追加削除も考えているのでしょうか。 それにもよるのですが。。。
_Taturon_

2020/05/20 09:43

前回の質問ではお世話になりました。 すでに関連付けられているsourceについてのみです。 一般的?なフォームですと、編集フォームへアクセス(/memos/:id/edit)した際にeditアクション( @memo = Memo.find(params[:id]))によってモデルから値が引っ張り出され、その値がフォームにあらかじめ入力された状態になりますよね?(違ってたらごめんなさい) これを関連付けた値でもやりたいのです 例えばmemo1にurl1とurl2が関連づけられて保存されていた場合に、memo1に対してeditアクションを実行してフォームに遷移した際に、Memoモデルに保存された値だけでなく、関連づけられたurl1,url2もフォームに最初から入力させた状態にしたいです 現状ですと、Memoモデルに保存した値しかeditのフォームに入力されません 説明が難しいです
guest

回答1

0

ベストアンサー

urlはSourceのものですので、memoの編集時にその値を修正することはしない、と考えてよいですね? 他のmemoでもつかっている可能性があるのですから。
すると f.url_field と入力fieldにするのではなく

memo.sources.each do | source | source.url end

と表示だけするのが妥当でしょう。
もしURLの修正も行いたいのでしたら

f.fields_for :sources do | fs | fs.url_field :url end

ですが、これだと def update がややこしくなります。
入れなおしたurlが他のsourceに既に有ったらどうするのか
同じsourceを参照していたほかのmemoは実は元のurlが正しいということは絶対ないのか
などをどう扱うのか、を考え、かつそれを実現する必要が出てきます

投稿2020/05/20 21:05

winterboum

総合スコア23324

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

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

_Taturon_

2020/05/21 09:29

winterboumさん、ご回答ありがとうございます。 自分でもいろいろ調べた結果、おっしゃられている通り、fields_forで実装してみようと思います。
_Taturon_

2020/05/21 14:19

いろいろ検討した結果、memoとurlを多対多では無く、一対多で実装することにいたしました。 理由としては、urlが重複する可能性が低いことと多対多で実装する技術力がないためです。 ただ、ここ数日間の学習でリレーションに関する知識はかなり強化されました。 2度にわたって回答して頂き誠にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問