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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

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

Q&A

解決済

1回答

1658閲覧

【Rails】チェックで選択した項目の個数と備考欄を付けて保存したい

ganchan

総合スコア7

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Ruby on Rails

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

0グッド

0クリップ

投稿2020/04/28 00:27

編集2020/05/11 05:44
  • 前提・実現したいこと

Railsで物件登録システムを作っています。
物件を登録する時に既に作られているモデルをチェックボックスから選択してそのチェックした個数と備考欄を子テーブルとして登録したいです。
このような要件の場合、どのようにしてチェックしたものを他情報を添えて登録することができるのでしょうか。
ご教示頂けますと幸いです。
なお質問要件の前はチェックしたものと物件を紐づけるのみでしたので、中間テーブルとして登録していました。
その時のモデルファイルが以下になります。

モデル

property

1 has_many :gifts, :dependent => :destroy 2 has_many :accessories, through: :gifts 3 accepts_nested_attributes_for :gifts, allow_destroy: true

gift

1 belongs_to :property, optional: true 2 belongs_to :accessory, optional: true

accessory

1 has_many :gifts 2 has_many :properties, through: :gifts 3

form

1 2_form.html.erb 3<%= form_with model:property, url:properties_path, local:true do |f| %> 4 5 <div class="container"> 6 7 <div class="row create-property-forms"> 8 <div class="col-7"> 9 10 <div class="card"> 11 <div class="card-header bg-gray">物件情報</div> 12 <div class="card-body"> 13 <!-- 基本情報 --> 14 <%= render :partial => "standard", :locals => { f: f } %> 15 <!-- テキストエリア --> 16 <%= render :partial => "textareas", :locals => { f: f } %> 17 <!-- 掲載期限 --> 18 <%= render :partial => "pereod", :locals => { f: f } %> 19 </div><!--左半分--> 20 21 <div class="col-5"> 22 <!-- 業態 --> 23 <%= render :partial => "business_lists", :locals => { f: f} %> 24 <!-- エリア --> 25 <%= render :partial => "area", :locals => { f: f} %> 26 <!-- 譲渡品 --> 27 <%= render :partial => "gifts", :locals => { f: f} %> 28 </div><!--右半分--> 29 30 </div><!--全体ラップ--> 31 </div><!--container--> 32 33 <div class="container"> 34 <!-- トップ画像 --> 35 <%= render :partial => "top_image", :locals => { f: f} %> 36 <!-- 複数画像 --> 37 <%= render :partial => "many_image", :locals => { f: f} %> 38 </div> 39 40 <!-- 追従 --> 41 <div class="fixed-box"> 42 <div class="container"> 43 <div class="d-flex justify-content-between"> 44 <div class=""> 45 <div class="secret-check"> 46 <label for="secret_check" name="会員のみ公開" class="text-white"> 47 <%= f.check_box :secret, cheked:true, id:"secret_check" %> 48 会員のみ公開</label> 49 </div> 50 <div class="recommend-check"> 51 <label for="recommend_check" name="おすすめに表示する" class="text-white"> 52 <%= f.check_box :recommend, cheked:true, id:"recommend_check" %> 53 おすすめに表示する</label> 54 </div> 55 </div> 56 <div class="my-2"><%= f.submit "登録", class:"btn btn-primary px-5 fixed-submit" %></div> 57 </div> 58 </div> 59 </div> 60 61<% end %><!-- formend --> 62 63<style media="screen"> 64 .last-margin { 65 margin-bottom: 10rem!important; 66 } 67 .station_select { 68 width: 200px; 69 } 70</style> 71 72 73 74<script type="text/javascript"> 75 76 $(document).ready(function(){ 77 $('#property_pref').change(function(){ 78 var pref_id = $('#property_pref') .val(); 79 $.get("/properties/city", 80 {pref_id: pref_id}, 81 function(data){} 82 ); 83 }) 84 85 $('#property_pref').change(function(){ 86 var pref_id = $('#property_pref') .val(); 87 $.get("/properties/station", 88 {pref_id: pref_id}, 89 function(data){} 90 ); 91 }) 92 }); 93 94</script>

gifts

1_gifts.html.erb 2 <div class="card my-2"> 3 <span class="card-header">譲渡品</span> 4 5 <div class="rounded card-body p-3 m-3 acc-table-innner" id="acc_chk"> 6 <%= f.collection_check_boxes(:accessory_ids, Accessory.all, :id, :name, include_hidden: false) do |b| %> 7 <%= b.label { b.check_box + b.text } %> 8 <div> 9 <%= f.number_field :stock, name: "property[gift][#{b.value}][stock]" %> 10 <%= f.text_field :remark, placeholder: "備考を入力" ,name: "property[gift][#{b.value}][remark] " %> 11 </div> 12 13 <% end %> 14 15 </div> 16 </div>

controller

1 def create 2 @property = Property.new(property_params) 3 4 respond_to do |format| 5 if @property.save! 6 7    # ギフト作成 8 params[:property][:accessory_ids].each do | accessory_id | 9 @property.gifts.create( 10 accessory_id: accessory_id, 11 stock: params[:property][:gift][accessory_id][:stock], 12 remark: params[:property][:gift][accessory_id][:remark] 13 ) 14 end 15 16 params[:property_images][:image].each do |image| 17 @property.property_images.create!(image: image, property_id: @property.id) 18 end 19 20 flash.now[:alert] = "#{@property.title}を作成しました。" 21     redirect_to property_new_path 22 else 23 flash.now[:alert] = "物件作成に失敗しました" 24 format.html { render :new } 25 format.json { render json: @property.errors, status: :unprocessable_entity } 26 end 27 end 28 end 29 30 private 31 def property_params 32 params.require(:property).permit(:title, :preperty_no,:control_num,:price,:deposit,:admin_const, 33 :othoer_price,:facility,:street_address,:traffic,:age,:area, 34 :floor,:parcel,:construction,:parking,:parking_exp,:contract_method,:contract_period,:time,:secret, 35 :recommend,:current_status,:list_comment,:detail_comment,:recommend_comment, :pref ,:city, :station, 36 :inu_or_suke, :end_on, :image, 37 area_tag_ids: [],category_ids: [], 38 preperty_images_attributes: [:image, :id, :_destroy]).merge(user_id: current.id) 39 end

イメージ図
イメージ図

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

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

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

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

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

winterboum

2020/05/06 08:35

わかりにくいところがいろいろあります。 Property に has_many :gifts, :dependent => :destroy とあるのに Accsesory にも has_many :gifts, :dependent => :destroy とあります。 どちらが間違い? Giftに belongs_to :item, とあります。 Itemってなにもの? formを呼び出す controller と formが送り込まれるcontroller(今のを)載せてください formをrenderしているviewも載せてください
ganchan

2020/05/06 11:58

追記いたしました。すみませんItemは丸ごとだと問題があるかなと勝手に思い込んで変更して掲載したものです。修正しました。
guest

回答1

0

ベストアンサー

このままでgiftにデータ入っていませんか?
accepts_nested_attributes_for :gifts, allow_destroy: true があり
<%=f.fields_for :gifts do |ff| %> <%= ff.select :stock, @num, <%= ff.text_field :remark %>
があり
def property_params params.require(:property).permit( gifts_attributes: [:property_id, :accessory_id, :stock, :remark],
がある。
気になるのは 
<%= form_with model:property, url:properties_path, local:true do
と properties_pathなのに create で受けているところですが、これで他のデータがsaveされているのならそこは合っているということですね。
stock、remark は入っていませんか?

追記:非スマート
_gifts.html.erb の
<%= gift.collection_check_boxes .... do |b| %> <% end %> の所の中身
`<%= b.label { b.check_box + b.text } %>

<div> <%= gift.select :stock, @num, {include_blank: '個数を入力'},name: "property[gift][#{b.value}][stock]" %> <%= gift.text_field :remark, placeholder: "備考を入力" ,name: "property[gift][#{b.value}][remark] " %> </div> ` controller#create の if @property.save! の後に ` gifts = params[:property][:gift][:accessory_id].each do | accessory_id | gift = params[:property][:gift][accessory_id] @property.gifts.create(accessory_id: accessory_id, stock: gift[:stock], remark: gift[:remark] ) end ` 辺りかな。 うまく行かなかったら、params見せてください

投稿2020/05/06 13:06

編集2020/05/08 08:32
winterboum

総合スコア23284

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

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

ganchan

2020/05/07 12:25

ありがとうございます。 今記載しているコードでのlogを見てみると giftの部分は "gift"=>{"accessory_id"=>["10", "11"], "stock"=>"", "remark"=>""}, となっており、フォームにstockとremarkを入力しているのにわたっていない状態です。 今はgiftは作られていません。 モデルの関連記述とfields_forの使い方が間違っているということでしょうか。 検証でのinputのnameは property[gift][accessory_id][] <チェックボックス> property[gift][stock] <個数> property[gift][remark]  <備考> となっています。 また "form_width"のurl先についてですが、createに向いているのでそこは問題なさそうです。 このようなケースを言語化して調べるのもワードが上手く見つからず頓挫しかけている状態です。 分からないままfields_forを使っているのでもう少し自分でも調べてまいります。
winterboum

2020/05/07 13:26

そかそか、入力エリアができているんで詳しく見てませんでした。 <%=f.fields_for :gifts do |ff| %> の中に有る <%= ff.select :stock, @num, {include_blank: "個数を入力"} %> <%= ff.text_field :remark %> の id、nameが皆同じですね。 paramsが params["gift_attributes"][32]["stock"] の様になっていないとcreateで自動に、はならないです。 accesory_id,stock,remarksのセットがアクセサリーの数だけ。 この32の所はgiftのid、まだ作られて居ない時はありえないid。 で、自動でなくても良い、としてもどのアクセサリーのstockなのかがわかる構造にする必要があります。 #今日はごめん疲れてるので明日。 # にしてもこのview疲れますね。フォーカスしてもスクロールするとどこだかわからなくなる。 # 機能毎にpartialにして構造がわかりやすいようにしたほうがよいかも
ganchan

2020/05/08 07:06

読みにくいコードになっていてすみません。パーシャル化しました。 全てのinput=nameがproperty[gifts_attributes][0][カラム名]になっており原因を調べています。
winterboum

2020/05/08 07:08

「原因を調べています。」いや原因はわかってます。。 ただ、このデータ構造のケースは私は初めてなので、どうしたらスマートな書き方が出来るか悩んでます。 スマートで無くてもよい?
winterboum

2020/05/08 07:09

パーシャル化したのに張り替えてよ、、、  ;_;
ganchan

2020/05/08 08:04

本当に申し訳ございません。ギフトのrender先を追記してformも修正しました。 スマートでない場合でもいいので知りたいです。
ganchan

2020/05/11 01:42

おはようございます。先日掲示頂きましたようにコード改変いたしましたところ Mysql2::Error: Field 'accessory_id' doesn't have a default value: INSERT INTO `gifts` (`property_id`, `created_at`, `updated_at`) VALUES (318, '2020-05-11 10:35:19', '2020-05-11 10:35:19') となりINSERTまではいきますが、ROLLBACKしてしまうようです。 paramsは "gifts_attributes"=>{"0"=>{"accessory_id"=>["10", "11"]}}, "gift"=>{"10"=>{"stock"=>"2", "remark"=>{" "=>"冷蔵庫"}}, "11"=>{"stock"=>"14", "remark"=>{" "=>"エアコン"}}, "13"=>{"stock"=>"", "remark"=>{" "=>""}}, "15"=>{"stock"=>"", "remark"=>{" "=>""}}}, となっております。
winterboum

2020/05/11 03:40

想定内の動きです。 まずroolbackしたのは 必須 の accessory_id が渡っていないからです。 gift"=>{" をみると checkしていなかったaccessoryの情報も来てますね。 "0"=>{"accessory_id"=>["10", "11"]}}, でCHECKしたaccessoryがわかるので、loopw回してgift"=>{" の数量などを得てGiftをつくる ということになりますが、やってみてください。 だめだったらhelpします
ganchan

2020/05/11 05:22

giftsを登録してチェックされたものに入っているremarkとstockも保存することができました! …ですが remark: "{\" \"=>\"エアコン\"}",という形で入ってしまっているようです。 paramsの "gift"=>{"10"=>{"stock"=>"2", "remark"=>{" "=>"冷蔵庫"}}とremarkの所のparamsが思っていた形になっていません。collection do の中に二つあってstockと同じ条件のはずなのですが…。
ganchan

2020/05/11 05:55

すみませんハッシュでremarkが入っている問題は自己解決しました。name=""の部分に余計な空欄があってそのせいでハッシュとしてつくられたようです。 何度もご指摘頂き登録まで無事にこぎ着けることができました。 ご迷惑おかけして申し訳ありませんでした。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問