🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

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

Ruby on Rails

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

データベース

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

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Q&A

解決済

2回答

2288閲覧

[Ruby on Rails]複数条件でAND検索し、その結果をビューで表示させたい

clora

総合スコア72

Ruby

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

Ruby on Rails

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

データベース

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

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

0グッド

1クリップ

投稿2019/12/14 03:26

編集2019/12/14 12:37

前提

複数の条件に一致した時のデータを取得したいと考えています
検索条件は日付(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 %>
iddategroup_idproduct_id
262019-12-13 00:00:0011

試したこと

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の違いや原理を理解していないのがエラーにハマった原因でした。

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

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

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

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

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

guest

回答2

0

ベストアンサー

def self.search(date,group_id,product_id)
if search

Production.searchメソッドの再帰呼び出しになります。
このsearchは何なのでしょうか?

Production.where ("(date = ?) AND (group_id = ?) AND (product_id = ?)", "%#{date}%", "%#{group_id}%", "%#{product_id}%")

ruby

1Production.where() 2("(date = ?) AND (group_id = ?) AND (product_id = ?)", "%#{date}%", "%#{group_id}%", "%#{product_id}%")

と解釈されます。


コメントに返信

redirect_to productions_searches_path

モデルのなかでredirect_toを使うのは避けた方がいいでしょう。
(そもそも使えないと思います。)

LIKE検索でもないのに%で囲む意味がよくわかりませんが

ruby

1Production.where(date: date). 2 where(group_id: group_id). 3 where(product_id: product_id)

ruby

1Production.where("(date = ?) AND (group_id = ?) AND (product_id = ?)", 2 date, group_id, product_id)

どっちでもよかったはずです。

投稿2019/12/14 04:12

編集2019/12/14 07:25
asm

総合スコア15149

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

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

clora

2019/12/14 04:47

指摘されて、ミスに気付きました。 そこは記述するならsearchではなく、date and group_id and product_idですね。 三つの条件を満たす結果があれば、@productionに検索結果を挿入して、もし条件を満たす物がなかったら、検索ページ(searchのsearchアクション)を呼び出す、という風に記述したかったのでした。 よくわからないまま引用してきた結果です。 修正しておきます。 その部分を修正したら、取り敢えず今出てるエラーは解決しました。検索結果の表示はうまくいっていないですが、、、。 ありがとうございます。先に進めたので、がんばってみようと思います。
clora

2019/12/14 06:42 編集

コメントの指摘を受けて、修正した内容を追記しました。
clora

2019/12/14 07:55

コメントありがとうございます。 指示通り修正してみたのですが、まだ undefined method `date' for nil:NilClass となってしまいますね、、、。
clora

2019/12/14 12:14

なんとか解決しました! 検索結果を挿入した@production_resultの型が普通の配列と違ったようで、ビューの方で取り出し方を下記のように変えたら、きちんと表示されるようになりました。 ありがとうございました。助けてもらったので自己解決ではありませんが、追記などをしてゴチャゴチャになったので、解決方法を自己解決の欄にまとめたいと思います。 お世話になりました。 <%= (@production_result.to_a)[0].date %>
asm

2019/12/14 12:19

あぁ、複数件ヒットすることを想定していないのを見逃していました。 whereをfind_byにした方がよさそうですね。
clora

2019/12/14 12:29

なるほど!find_byだと @production_result.date みたいな表記でできますね。find_byとwhereの違いを調べてみたのですがよくわかりません(笑) find_byは一個しかデータを取ってこないが、whereだと、複数の行のデータが入っているから、きちんと何番目か指定してあげないと取り出せない、みたいな感じでしょうか。 長々とありがとうございました。お世話になりました。
guest

0

アドバイスを沢山もらったので自己解決ではないですが、追記を繰り返して見辛いので、最終的なコードを示しておきたいと思います。
検索結果は基本的に複数件ヒットすることはないので、find_byを使うことにしました。
途中で作ったresultアクションは使わないので削除しました。

ruby

1# routes.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# models/production.rb 2def self.search(date,group_id,product_id) 3 Production.find_by("(date = ?) AND (group_id = ?) AND (product_id = ?)", 4 date, group_id, product_id) 5end 6

ruby

1#searches_controller.rb 2class Productions::SearchesController < ApplicationController 3 def index 4 @production = Production.new 5 end 6 7 def search 8 product_id = Product.find_by(code: params[:production][:product_id]).id 9 10 @production_result = Production.search(params[:production][:date], params[:production][:group_id], product_id) 11 end 12end

html

1#search.html 2検索結果 3<%= (@production_result.date %> 4<%= (@production_result.group_id %> 5<%= (@production_result.product_id %> 6

投稿2019/12/14 12:50

clora

総合スコア72

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問