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

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

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

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

Ruby on Rails

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

Q&A

解決済

1回答

1277閲覧

Rails each文でindexに表示された要素の取得について

liloi94

総合スコア1

Ruby

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

Ruby on Rails

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

0グッド

0クリップ

投稿2020/05/01 17:14

編集2020/05/04 11:56

プログラミング初心者です
railsの基礎勉強が終わったので、このコロナのご時世にあやかって、
簡単な受発注システムをrailsで試しに作ってみようと思い、自分なりにモデルなどの構造を考え現在以下のような構想で作業を進めております。

①まずはproductテーブルに商品情報を登録しました。
②次に、order(s)テーブル・モデル・コントローラーを作成
③order(s)にCRUDの仕組み+selectというアクション、viewにも(order.)select.html.erbを作成しました
④まずはselectで商品を選んでもらい、その情報をもって(order.)new.html.erbにリダイレクトした後、数量や納期などを指定(入力)してもらい、オーダーテーブルにデータとして保存する。

それで、今④の途中でつまずきました。
productテーブルの情報をselect actionで@product.allを定義し、(order.)select.html.erbにeach文でループで表示しています。
それに加え、各行にラジオボタンを追加し、それを選択すると、その行ごとデータを取得できる仕組みをjqueryで作りました。

発生している問題・エラーメッセージ

そこまではうまくいっておりますが、そのあと、submitボタンを押し、(order.)new.html.erbにredirectすると、どの行を選択しても、productテーブルの一番最後のデータが(order.)new.html.erb反映されます。
redirectする前は、確かに選んだ行を取得しているようなのです。
(⇒(order.)select.html.erb画面で選択すると、その値がページ最下部にテスト用に入れたhtmlにしっかりと反映されています)

なぜredirectすると一番最後の行の値が入るのでしょうか?
原因と解決方法を教えていただけないでしょうか。

該当のソースコード

[routing] Rails.application.routes.draw do root "top#index" get "orders/select" => "orders#select" post "orders/select" => "orders#select" post "orders/new" => "orders#new" resources :products resources :orders end
[Orders.controlle.rb] class OrdersController < ApplicationController def index @orders = Order.all end def select @products = Product.all end def new @name = params[:name] @quantity_per_catron = params[:quantity_per_catron] end
[(orders.)select.html.erb] <% @page_title = "製品マスタ" %> <h2><%= @page_title %></h2> <%= link_to "製品マスタの新規登録", :new_product %> <table> <thead> <tr> <th></th> <th>製品名</th> <th>入目(kg)</th> <th>パッケージ</th> <th>原産地(kg)</th> <th></th> </tr> </thead> <tbody> <%= form_tag orders_new_path do %> <% @products.each do |product| %> <tr> <td><input type="checkbox" class="selectBtn"></td> <td><input type="text" name="name" value="<%= product.name %>"></td> <td><input type="text" name="quantity_per_catron" value="<%= product.quantity_per_catron %>"></td> <td><input type="text" value="<%= product.package %>"></td> <td><input type="text" value="<%= product.origin %>"></td> </tr> <% end %> <%= submit_tag %> <% end %> </tbody> </table> --ここからテスト用-- <span>name1: </span><span id="productsname1"></span> <span>name2: </span><span id="productsname2"></span>
[(orders.)new.html.erb] <div class="toolbar"><%= link_to "オーダー選択に戻る", :orders_select, data: {"turbolinks" => false} %></div> <%= form_with model: @order, url: orders_path, method: :post do |f| %> <table> <tr> <th>製品</th> <th>入目(kg)</th> </tr> <tr> <td><input type="text" name="name" value="<%= @name %>"></td> <td><input type="integer" name="quantity_per_catron" value="<%= @quantity_per_catron %>"></td> </tr> </table> <div><%= f.submit %></div> <% end %>
[application.js] jQuery(function($){ $(".selectBtn").on("click", function(){ var name1 = $(this).closest('tr').find('input[name=name]').val(); $("#productsname1").text(name1); var name2 = $(this).closest('tr').find('input[name=quantity_per_catron]').val(); $("#productsname2").text(name2); }); });

試したこと

new actionでwhereでnameをparamsで取得すれば、選択した行を取得できるかと思いましたがうまくいきませんでした。
(例)
def new
@product = Product.where(name: params[:name])
@product.name = params[:name]
@product.quantity_per_catron = params[:quantity_per_catron]
end

補足情報(FW/ツールのバージョンなど)

↓のやり方で結局うまくいきませんでした。
もしかしたら、new.html.erbが間違っているのでしょうか?

最初質問した際に、記載していたコードが間違っておりました、
実際は↓のように記載しています。
@product.nameとしていたところが、実際は@name
@product.quantity_per_catronとしていたところが、実際は@quantity_per_catron
です。

[(orders.)new.html.erb] <div class="toolbar"><%= link_to "オーダー選択に戻る", :orders_select, data: {"turbolinks" => false} %></div> <%= form_with model: @order, url: orders_path, method: :post do |f| %> <table> <tr> <th>製品</th> <th>入目(kg)</th> </tr> <tr> <td><input type="text" name="name" value="<%= @name %>"></td> <td><input type="integer" name="quantity_per_catron" value="<%= @quantity_per_catron %>"></td> </tr> </table> <div><%= f.submit %></div> <% end %>

ここにより詳細な情報を記載してください。

【orders.controller.rb】 def select @products = Product.all end def new @product = Product.new @product = Product.find_by(id: params[:product_id]) @product_name = params[:name] @product_quantity_per_catron = params[:quantity_per_catron] @order = Order.new end
【new.html.erb】 <% @page_title = "新規オーダー" %> <h2><%= @page_title %></h2> <div class="toolbar"><%= link_to "オーダー一覧に戻る", :orders, data: {"turbolinks" => false} %></div> <div class="toolbar"><%= link_to "オーダー選択に戻る", :orders_select, data: {"turbolinks" => false} %></div> <%= form_with model: @order do |f| %> <table> <tr> <th>製品</th> <th>入目(kg)</th> <th></th> <th>個数</th> <th></th> <th>amount(kg)</th> <th>納期</th> <th>納品先</th> <th>納品先住所</th> </tr> <tr> <td><input type="text" name="product_name" value="<%= @product.name %>"></td> <td><input type="integer" id="sample1" size=8 value="<%= @product.quantity_per_catron %>"></td> <td>×</td> <td><input type="select" name="sample2" id="sample2" size=8></td> <td>=</td> <td><input type="integer" name="quantity" id="result" size=15></td> <td><input type="date" name="due_date" %></td> <td><input type="text" name="delivery_name" value="" size=25></td> <td><input type="text" name="delivery_address" value="" size=45></td> </tr> </table> <div><%= f.submit %></div> <% end %>

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

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

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

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

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

guest

回答1

0

ベストアンサー

<% @products.each do |product| %> のloopの中のinputはどの行もみな同じ name をもっています。
こういう場合、ブラウザーは最後の要素の値を返します。
なのでどこを選んでも最後の行のデータが送られるわけです。

いろいろ方法はありますが、 productのidだけ渡ればよいのだと思いますから
<input type="checkbox" class="selectBtn"> を
<%= check_box_tag("product_id[]", product_id,class: "selectBtn" %>
としてみてください。
params => {"product_id" => [38] }
みたいのが返ると思います。

追記
new が悪いというより、そこで送られてきたparamsをきちんと処理していないからです。
<%= check_box_tag("product_id[]", product.id, false, class: "selectBtn") %>
としたところでsubmitした時のlogを見てください。
Parameters: {。。。。。, "product_id"=>[35]}
のように、checkをいれたProductのidが戻ってきていると思います。
(でないとするとcheck-boxハンドリングのjsの問題)
そのidを使って、productの情報を得てください。
paramsで送り込まれているその他のproductの値"name""quantity_per_catron"は一番最後の行のもののままです。これは最初に説明したとおり。そこが変わるような修正をしていませんから、渡ってきたnameを見ているのでは変わりません

投稿2020/05/02 07:54

編集2020/05/03 13:56
winterboum

総合スコア23329

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

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

liloi94

2020/05/02 16:44

ありがとうございます。 どうもうまくいきません。 1日ネットで調べましたが、解決できませんでした。 もう一度教えていただけないでしょうか。 undefined local variable or method `product_id' for #<#<Class:0x00007fbb88f2fd00>:0x00007fbb7c346478> Did you mean? product product_url @products とエラーがでます。 params => {"product_id" => [38] }はどこかに入力するのでしょうか?
winterboum

2020/05/02 21:01

間違えた <%= check_box_tag("product_id[]", :product_id,class: "selectBtn" %> product_idの前のコロンを落としてました params => {"product_id" => [38] }は 送られてくるパラメーターのことです。入力する必要はありません。
liloi94

2020/05/03 02:24 編集

ありがとうございます 試してみましたが、全部のcheck boxが選択された状態になっておりました。 こちらは:checked => falseで解除できました 一番上の行だけチェックをつけてsubmitしても、やはり一番最後の行のデータが反映されていました。 一番最初にいただいたご回答より、”productのidだけ渡ればよい”とのことですが、 この記載いただいている<%= check_box_tag("product_id[]", :product_id,class: "selectBtn" %>にidを渡す要素が含まれているのでしょうか? controllerなどに記載は不要でしょうか?
winterboum

2020/05/03 02:45

書き直したviewを載せてください。 POSTした時のlogを載せてください
liloi94

2020/05/03 03:27

何度もありがとうございます。 【ログ (2行目を選択して、submitした時)】 Started POST "/orders/new" for ::1 at 2020-05-03 12:24:20 +0900 Processing by OrdersController#new as HTML Parameters: {"commit"=>"Save changes", "utf8"=>"✓", "authenticity_token"=>"tAH1e7ElaNCz9QANIva6P/GnxaGh5Apz8XZ2S5YO3vP9PfMIZsbaD64V9mQBjNDPfvyI7a4q8NEtiZVqXmOOJw==", "name"=>"FFFFFFFF, "quantity_per_catron"=>"25", "product_id"=>["product_id"]} Rendering orders/new.html.erb within layouts/application Rendered orders/new.html.erb within layouts/application (22.7ms) Completed 200 OK in 198ms (Views: 183.4ms | ActiveRecord: 0.0ms) 【view】 <% @page_title = "製品マスタ" %> <h2><%= @page_title %></h2> <%= link_to "製品マスタの新規登録", :new_product %> <table> <thead> <tr> <th></th> <th>製品名</th> <th>入目(kg)</th> <th>パッケージ</th> <th>原産地(kg)</th> <th></th> </tr> </thead> <tbody> <%= form_tag orders_new_path do %> <% @products.each do |product| %> <tr> <td><%= check_box_tag("product_id[]", :product_id, checked = false, class: "selectBtn") %></td> <td><input type="text" name="name" value="<%= product.name %>"></td> <td><input type="text" name="quantity_per_catron" value="<%= product.quantity_per_catron %>"></td> <td><input type="text" value="<%= product.package %>"></td> <td><input type="text" value="<%= product.origin %>"></td> </tr> <% end %> <%= submit_tag %> <% end %> </tbody> </table> <span>name1: </span><span id="productsname1"></span> <span>name2: </span><span id="productsname2"></span>
winterboum

2020/05/03 09:53

code、log,エラーメッセージなどは コメント欄ではなく質問を編集してそちらに書くようにしてください。 他の回答者にわかりにくいのと、インデントがなくなるので読みにくいのです。
winterboum

2020/05/03 09:57

<%= check_box_tag("product_id[]", :product_id, checked = false, class: "selectBtn") %> のところ <%= check_box_tag("product_id[]", product.id, false, class: "selectBtn") %> に
liloi94

2020/05/03 10:38

すみません。 やはりできませんでした。 質問に補足書きましたので、もう一度ご確認いただけないでしょうか。
liloi94

2020/05/04 11:51

できました②! controllerとnewのviewかえたらいけました。 ↑にコード載せましたので、もしよろしければこれであってるか確認お願いいたします。 余分なコードがあったり、全然違うやり方であれば正しい答えを教えていただけますと幸甚です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問