前提
複数の条件に一致した時のデータを取得したいと考えています
検索条件は日付(date) AND グループid(group_id) AND 製品id(product_id)の三つです。
検索条件の三つの値をフォームに入力して検索しようとすると、
wrong number of arguments (given 0, expected 3)
という、エラーが出てしまいます。
これは、引数が渡せていないというエラーだということはわかっているのですが、検索の条件を満たす、引数を3つ渡した時だけ、given 0、となってしまいます。
試しに、渡す引数の数を一つや二つにすると、given 1,given 2となるので、引数は渡せていて、メソッドも呼び出されていると思うのですが(もちろんエラーは出ます)、引数を三つ渡した時だけエラーメッセージがgiven 0となり、検索できません。
searchメソッドの記述などを間違えているのでしょうか。それとも、引数の渡し方がおかしいのでしょうか。
DBには該当するデータは存在しています。
よろしくお願い致します。
発生している問題・エラーメッセージ
ArgumentError in Productions::SearchesController#search wrong number of arguments (given 0, expected 3) Extracted source (around line #8): 8 def self.search(date,line_id,product_id) 9 if search 10 Production.where ("(date = ?) AND (line_id = ?) AND (product_id = ?)", "%#{date}%", "%# {group_id}%", "%#{product_id}%") 11 redirect_to productions_searches_path
該当のソースコード
ruby
1#route.rb 2Rails.application.routes.draw do 3 root 'groups#index' 4 namespace :productions do 5 resources :searches, only: :index do 6 collection do 7 get 'search' 8 end 9 end 10 end 11 12 resources :groups do 13 resources :productions 14 end 15end
ruby
1#/controllers/productions/searches_controller.rb 2class Productions::SearchesController < ApplicationController 3 def index 4 @production = Production.new 5 end 6 7 def search 8 #Productモデルのcodeカラムに情報を取りにいってます 9 product_id = Product.find_by(code: params[:production][:product_id]).id 10 11 @production = Production.search(params[:production][:date], params[:production][:group_id], product_id) 12 redirect_to search_productions_searches_path 13 end 14end
ruby
1#models/production.rb 2class Production < ApplicationRecord 3 belongs_to :product 4 belongs_to :group 5 6 validates :date, presence: true 7 validates :product_id, presence: true 8 9def self.search(date,group_id,product_id) 10 if search 11 Production.where 12 ("(date = ?) AND (group_id = ?) AND (product_id = ?)", "%#{date}%", "%#{group_id}%", "%#{product_id}%") 13 else 14 redirect_to productions_searches_path 15 end 16end
html
1-# views/productions/searches/index.html 2<%= form_for [@production], url: search_productions_searches_path do |f| %> 3 <div class="form__info__date"> 4 <%= f.date_field :date %> #日付の入力 5 <%= f.number_field :products_id %> #productsのid(数字)を入力 6 <%= f.select :group_id, [["グループ1", 1],["グループ2", 2]] %> #グループidの入力 7 <%= f.submit '検索', class: "btn" %> 8 </div> 9<% end %>
html
1-# views/productions/searches/search.html 2-# 検索結果の出力画面は仮です 3<%= @production.date %> 4<%= @production.group_id %> 5<%= @production.product_id %>
試したこと
SearchesControllerのsearchメソッドを呼ぶ前でbinding pryして検索条件がきちんと入力されているか、確かめました。
ruby
1#/controllers/productions/searches_controller.rb 2def search 3 #Productモデルのcodeカラムに情報を取りにいってます 4 product_id = Product.find_by(code: params[:production][:product_id]).id 5 binding pry 6 @production = Production.search 7 (params[:production][:date], params[:production][:group_id], product_id) 8end
ruby
1[1] pry(#<Productions::SearchesController>)> product_id 2=> 1 3[2] pry(#<Productions::SearchesController>)> params[:production][:group_id] 4=> "1" 5[3] pry(#<Productions::SearchesController>)> params[:production][:date] 6=> "2019-12-13"
この内容を見ると、値がnilにはなっていないとは思います。しかし、product_idがint型、group_idがstr型なのが気になりますが。
また、仮で、下記のようにsearchメソッドに直接数字などを渡してもやはり、三つ渡した時だけ、given 0となってしまいエラーになってしまいます。
ruby
1#/controllers/productions/searches_controller.rb 2@production = Production.search("2019-12-13", "1", "1") 3 4@production = Production.search("2019-12-13", 1, 1) 5
実現したいこと
三つの条件を入力して、該当するデータを取得する
補足情報(FW/ツールのバージョンなど)
rails 5.0.7
ruby 2.5.1
追記
コメントで指摘を受けた部分を変更しました。
それに加えて、resultアクションを追加して、@production_resultに検索結果を挿入し、resultアクションで検索結果を表示させるようにしました。
しかし、@production_resultがnilになってしまい検索結果が表示されません。
どうもsearchメソッドを使用すると、@production_resultがから([])となってしまいます。
これは、検索結果がないということなのでしょうか?配列の中の値がnilとして返ってくるのならわかるのですが、配列自体が空になってしまいます。まだ、searchメソッドの記述がおかしいのでしょうか。
下記はsearchメソッドを使用した後、binding pryで確かめた結果です。
[1] pry(Production)> @production_result => nil
ruby
1#route.rb 2Rails.application.routes.draw do 3 root 'groups#index' 4 namespace :productions do 5 resources :searches, only: :index do 6 collection do 7 get 'search' 8 end 9 collection do 10 get 'result' 11 end 12 end 13 end 14 15 resources :groups do 16 resources :productions 17 end 18end
ruby
1#/controllers/productions/searches_controller.rb 2def search 3 @production_result = Production.new 4 product_id = Product.find_by(code: params[:production][:product_id]).id 5 @production_result = Production.search(params[:production][:date], params[:production][:group_id], product_id) 6 7 redirect_to result_productions_searches_path(@production_result) 8end 9 10def result 11 12end
ruby
1def self.search(date,line_id,product_id) 2 if date and group_id and product_id 3 Production.where 4 ("(date = ?) AND (group_id = ?) AND (product_id = ?)", "%#{date}%", "%#{group_id}%", "%#{product_id}%") 5 else 6 redirect_to productions_searches_path 7 end 8end
html
1-#views/productions/searches/result.html 2検索結果 3<%= @production_result.date %> 4<%= @production_result.group_id %> 5<%= @production_result.product_id %>
id | date | group_id | product_id |
---|---|---|---|
26 | 2019-12-13 00:00:00 | 1 | 1 |
試したこと
binding pryをしてみたところ、seaechメソッドをすると@production_resultが[]となってしまいます。
追記 part2
上記の状況から進展がありました。
@production_resultがnilになってしまうのはproduct_idの指定の仕方が間違えていたことによるものでした。
上の方にも書いた通り、product_idは他のテーブルに値を探しにいって変数product_idに入れて、searchメソッドに渡しています。その時にフォームから直接受け取ったgroup_idは"1"となっていたのに対し、product_idは 1 となっていました。そのため、そのまま、product_idを検索条件に入れてしまうと、条件に引っかからず、検索結果が0となり、@production_resulがnilになっているのでしたそこで下記のように、searchメソッドを書き直したところ、きちんと検索結果が、@production_resultに入ってくれました。
ruby
1#production.rb 2def self.search(date,line_id,product_id) 3 Production.where(date: date). 4 where(group_id: group_id). 5 where(product_id: "#{product_id}") 6end
ruby
1[1] pry(#<Productions::SearchesController>)> product_id 2=> 1 #こっちはただの数字 3[2] pry(#<Productions::SearchesController>)> params[:production][:group_id] 4=> "1" #こっちはダブルクォーテーションで囲まれている
ただ、まだ検索結果のビューでは、@production_resulはnilclassになってしまいますね、、、。
うまく変数が渡せていないだけだと思うのですが、、、。
追記 part3
なんとか解決しました。
ビューの方の表記を変えたところきちんと検索結果が表示されました。
html
1間違い 2<%= @production_result.date %> 3 4正解 5<%= (@production_result.to_a)[0].date %>
また、asmさんのアドバイス通りwhereでなく、find_byを使えば@production_result.dateという形でも取り出せます。whereやfind_byの違いや原理を理解していないのがエラーにハマった原因でした。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/12/14 04:47
2019/12/14 06:42 編集
2019/12/14 07:55
2019/12/14 12:14
2019/12/14 12:19
2019/12/14 12:29