前提・実現したいこと
railsで趣味を登録、検索できるサービスを作ろうとしています。
発生している問題・エラーメッセージ
index画面で検索機能を実装したいのですが、フォームに検索ワードを打ち込んでも常に一覧が表示されます。
該当のソースコード
view/user/hobbies/index.html.erb
<div class="table-wrapper"> <%= render "search_form" %> <table class="listing"> <!- search結果が一覧になる-> <% @hobbies.each do |h| %> <% p = HobbyPresenter.new(h, self) %> <tr> <td><%= p.name %></td> <td><%= p.initial_investment %></td> <td><%= p.running_cost %></td> <td><%= p.frequency %></td> <td><%= p.place %></td> <td><%= p.number %></td> </tr> <% end %> </table> </div>
view/user/hobbies/_search_form.html.erb
<%= form_with model: @search_form, scope: "search", url: :user_hobbies, html: { method: :get, class: "search" } do |f| %> <%= markup do |m| p = FormPresenter.new(f, self) m << p.text_field_block(:name, "名称:") m.br m << p.text_field_block(:initial_investment, "初期投資:") m << p.text_field_block(:running_cost, "ランニングコスト:") m.br m << p.text_field_block(:frequency, "頻度:") m << p.text_field_block(:place, "場所:") m << p.text_field_block(:number, "人数:") m.br m << f.submit("検索") end %> <% end %>
form/user/hobby_search_form.rb(修正後)
class User::HobbySearchForm include ActiveModel::Model attr_accessor :name, :initial_investment, :running_cost, :frequency, :place, :number def initialize(search_params = {}) @name = search_params[:name] @initial_investment = search_params[:initial_investment] @running_cost = search_params[:running_cost] @frequency = search_params[:frequency] @place = search_params[:place] @number = search_params[:number] end def search rel = Hobby if name.present? rel = rel.where(name: name) end rel = rel.where(initial_investment: initial_investment) if initial_investment.present? rel = rel.where(running_cost: running_cost) if running_cost.present? rel = rel.where(frequency: frequency) if frequency.present? rel = rel.where(place: place) if place.present? rel = rel.where(number: number) if number.present? rel.order(:id) end end
試したこと
Rails実践ガイドの機能拡張編を参考にしながらやってみたのですが、実力不足すぎてこの不具合に何時間も足止めされています。
補足情報(FW/ツールのバージョンなど)
presenters/form_presenter.rb
class FormPresenter include HtmlBuilder attr_reader :form_builder, :view_context delegate :label, :text_field, :date_field, :password_field, :check_box, :radio_button, :text_area, :object, to: :form_builder def initialize(form_builder, view_context) @form_builder = form_builder @view_context = view_context end def notes markup(:div, class: "notes") do |m| m.span "*", class: "mark" m.text "印の付いた項目は入力必須です。" end end def text_field_block(name, label_text, options = {}) markup(:div, class: "input-block") do |m| m << decorated_label(name, label_text, options) m << text_field(name, options) m << error_messages_for(name) end end def password_field_block(name, label_text, options = {}) markup(:div, class: "input-block") do |m| m << decorated_label(name, label_text, options) m << password_field(name, options) m << error_messages_for(name) end end def date_field_block(name, label_text, options = {}) markup(:div, class: "input-block") do |m| m << decorated_label(name, label_text, options) m << date_field(name, options) m << error_messages_for(name) end end def drop_down_list_block(name, label_text, choices, options = {}) markup(:div, class: "input-block") do |m| m << decorated_label(name, label_text, options) m << form_builder.select(name, choices, { include_blank: true }, options) m << error_messages_for(name) end end def error_messages_for(name) markup do |m| object.errors.full_messages_for(name).each do |message| m.div(class: "error-message") do |m| m.text message end end end end def decorated_label(name, label_text, options = {}) label(name, label_text, class: options[:required] ? "required" : nil) end end
presenters/hobby_presenter.rb
class FormPresenter include HtmlBuilder attr_reader :form_builder, :view_context delegate :label, :text_field, :date_field, :password_field, :check_box, :radio_button, :text_area, :object, to: :form_builder def initialize(form_builder, view_context) @form_builder = form_builder @view_context = view_context end def notes markup(:div, class: "notes") do |m| m.span "*", class: "mark" m.text "印の付いた項目は入力必須です。" end end def text_field_block(name, label_text, options = {}) markup(:div, class: "input-block") do |m| m << decorated_label(name, label_text, options) m << text_field(name, options) m << error_messages_for(name) end end def password_field_block(name, label_text, options = {}) markup(:div, class: "input-block") do |m| m << decorated_label(name, label_text, options) m << password_field(name, options) m << error_messages_for(name) end end def date_field_block(name, label_text, options = {}) markup(:div, class: "input-block") do |m| m << decorated_label(name, label_text, options) m << date_field(name, options) m << error_messages_for(name) end end def drop_down_list_block(name, label_text, choices, options = {}) markup(:div, class: "input-block") do |m| m << decorated_label(name, label_text, options) m << form_builder.select(name, choices, { include_blank: true }, options) m << error_messages_for(name) end end def error_messages_for(name) markup do |m| object.errors.full_messages_for(name).each do |message| m.div(class: "error-message") do |m| m.text message end end end end def decorated_label(name, label_text, options = {}) label(name, label_text, class: options[:required] ? "required" : nil) end end
controllers/user/hobbies_controller.rb(修正後)
class User::HobbiesController < User::Base def index @search_form = User::HobbySearchForm.new(search_params) @hobbies = @search_form.search end def new @hobby = Hobby.new end def create @hobby = Hobby.new(hobby_params) if @hobby.save redirect_to user_hobby_path(@hobby.id), notice: "Hobby #{@hobby.name}を登録しました" else render "new" end end def show @hobby = Hobby.find_by(params[:hobby_id]) end private def hobby_params params.permit(:name, :initial_investment, :running_cost, :frequency, :place, :number) end def search_params params.permit(:search).permit(:name, :initial_investment, :running_cost, :frequency, :place, :number) end end
検索時のログ
Hobby Load (0.6ms) SELECT "hobbies".* FROM "hobbies" WHERE "hobbies"."name" = $1 ORDER BY "hobbies"."id" ASC [["name", "ランニング"]]
Controllerは?
回答1件
あなたの回答
tips
プレビュー