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

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

詳細はこちら
Ruby

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

Ruby on Rails 6

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

Slim

SlimはPHPアプリケーションを開発するための軽量なマイクロフレームワークです。

Q&A

2回答

2178閲覧

Railsで年齢月齢の範囲検索機能を実装したい

shogohori1988

総合スコア0

Ruby

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

Ruby on Rails 6

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

Slim

SlimはPHPアプリケーションを開発するための軽量なマイクロフレームワークです。

0グッド

0クリップ

投稿2020/12/21 10:19

編集2020/12/24 15:24

前提・実現したいこと

現在Railsで子育ての相談サイトを作成しています。
検索機能として年齢月齢の範囲検索を実装しようとしていますが、どのように実装すればよいかわかりません。
現状、DBの相談テーブルは年齢、月齢それぞれint型でカラムを分けています。
下記ビューのように、年齢月齢それぞれにgteq(以上)、lteq(以下)と記載しても正しい検索ができません。
例えば、0歳9ヶ月〜1歳11ヶ月で検索すると、月齢9〜11ヶ月内でしか検索されず、1歳1〜8ヶ月は検索されません。

下記の例のように年齢、月齢を組み合わせた値で検索する必要がありますが、
どのように実装すればよいかがわかりません。
どうすればよいか教えていただきたく、何卒お願いします。

例: 1歳3ヶ月 → 103

【環境】
MacBook Catalina ver.10.15.7

Rails 6.0.3

ruby 2.7.1

gem "ransack"

該当のソースコード

【テーブル定義書】
イメージ説明

【コントローラー】

Ruby

1#app/controllers/application_controller.rb 2class ApplicationController < ActionController::Base 3 before_action :set_search 4 5 def set_search 6 @q = Consultation.ransack(params[:q]) 7 @q.sorts = 'updated_at desc' if @q.sorts.empty? 8 @search_consultations = Kaminari.paginate_array(@q.result).page(params[:page]).per(5) 9 end 10end

【ビュー】

slim

1= search_form_for @q do |f| 2. 3. 4 .form-group 5 .form-inline 6 .col 7 = f.label :child_age, '年齢:' 8 .col 9 = f.select :child_age_gteq, options_for_select((0..3).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 10 | 歳 11 .form-inline 12 .col 13 = f.label :child_age, '月齢:' 14 .col 15 = f.select :child_moon_age_gteq, options_for_select((0..11).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 16 | ヶ月 17 | 〜 18 .form-inline 19 .col 20 = f.label :child_age, '年齢:' 21 .col 22 = f.select :child_age_lteq, options_for_select((0..3).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 23 | 歳 24 .form-inline 25 .col 26 = f.label :child_age, '月齢:' 27 .col 28 = f.select :child_moon_age_lteq, options_for_select((0..11).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 29 | ヶ月 30. 31. 32 = f.submit '検索する', class: 'btn btn-primary' 33

追記(2020/12/24)

DBの相談テーブルのchild_age(年齢)、child_moon_age(月齢)をカラムを削除し、child_age_moon_age(月齢の累積)として管理することとしました。出入力に関しては年齢、月齢を分けるために相談モデル(app/models/consultation.rb)にattr_accessor :age, :moon_age追加しました。
しかし、ransackで:age, :moon_ageメソッドを定義する方法がわかりません。
どのようにすれば定義できるのか教えていただきたく、何卒お願いします。

【ビュー】

slim

1= search_form_for @q do |f| 2. 3. 4 .form-inline 5 .col 6 = f.label :age, '年齢:' 7 .col 8 = f.select :age_gteq , options_for_select((0..3).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 9 | 歳 10 .form-inline 11 .col 12 = f.label :moon_age, '月齢:' 13 .col 14 = f.select :moon_age_gteq, options_for_select((0..11).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 15 | ヶ月 16 | 〜 17 .form-inline 18 .col 19 = f.label :age, '年齢:' 20 .col 21 = f.select :age_lteq, options_for_select((0..3).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 22 | 歳 23 .form-inline 24 .col 25 = f.label :moon_age, '月齢:' 26 .col 27 = f.select :moon_age_lteq, options_for_select((0..11).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 28. 29. 30 = f.submit '検索する', class: 'btn btn-primary'

【エラー】

ActionView::Template::Error (undefined method `age_gteq' for #<Ransack::Search:0x00007fbf79f8ff80>): 24: .col 25: = f.label :age, '年齢:' 26: .col 27: = f.select :age_gteq , options_for_select((0..3).to_a), { include_blank: '選択'}, class: 'selectpicker form-control' 28: | 歳 29: .form-inline 30: .col

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

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

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

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

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

no1knows

2020/12/21 10:47

年齢・月齢は生年月日の入力にすることはできないのでしょうか?
dodox86

2020/12/21 10:50

Railsは分からないのですけど、年齢、月齢を特に分ける必要があるのでしょうか。年齢は月齢(月)を単位にすると12単位に相当するので、例えば2歳10ヶ月なら 12*2 + 10 で34ヶ月です。34ヶ月を12で割れば2歳だし、12で割ったあまりは10で、月齢になります。月齢の累積(と言ってよいのか)で扱えばよいのではないですか。
gouf

2020/12/21 11:49

「@q」に対して「.to_sql」メソッドは呼び出せますか? もし呼び出し可能な場合、質問欄に追記できますか?
shogohori1988

2020/12/23 12:51

コメントいただきありがとうございます。現在、年齢、月齢を取りやめ、すべて月齢にします。 また、「@q」に対して「.to_sql」は呼び出せませんでした。
guest

回答2

0

少し面倒ですが、年齢月齢それぞれを一度文字列に直し、2つをくっ付けたものをもう一度数字に直してみてはどうですか?

total_age = "#{child_age} + #{child_moon_age}" total_number_age = total_age.to_i

変数名は適当です。すみません、初学者なもので参考にならないかも知れませんが、よろしくお願い致します。

投稿2021/01/09 09:53

tekeTECH

総合スコア8

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

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

0

やれなくはないですが 1ステージUPです。
かつRansacでやるには更に1,2ステージUPです。
かなり理解困難なcodeになりますから、ここは 年齢、月齢をやめ全部月齢で入れてそれを入出力で年齢、月齢に分けることをお薦めします。

実はそれでもRansacに食わせるには1細工必要になりますが。
child_moon、child_moon_age を止めchild_age_moon_age(仮称)を作ります
Ransac では age、moon_age でfiledを作ります。child_moon_ageなどが残っている間はそれらにすると干渉するのでよくないです。ただし、attr_accessor :age, :moon_age が必要かも。
action index では
params[:q][:child_age_moon_age_lteq] = params[:q][:age_lteq].to_i * 12 + params[:q][:moon_age_lteq].to_i
します。
本来なら [:age_lteq]または[:moon_age_lteq] が入力されていたら
のifが必要ですが、この場合は幸い ≧ 0 になるから要らないでしょう。

投稿2020/12/22 23:14

winterboum

総合スコア23567

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

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

shogohori1988

2020/12/24 15:32

回答頂きありがとうございます。 年齢、月齢をやめ全部月齢で登録できるようにしました。しかしRansackでの検索機能がうまくいきません。詳しくは質問内容に追記しましたのでわかりましたらご回答頂きたく、よろしくお願いします。
winterboum

2020/12/24 23:00

1.「attr_accessor :age, :moon_age が必要かも。」はしましたか
shogohori1988

2020/12/25 01:11

attr_accessor :age, :moon_ageは相談モデル(app/models/consultation.rb)に追加しました。 Ransack上でどうやって上記メソッドを定義すればよいのかがわかりません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問