On my events index page, I have a search form that filters the records on the index page based on those search parameters through Ransack.
The search form currently works only when the dance styles and/or event types (both of which are arrays) have one value each, however I would like to be able to search by multiple values of both.
Here's my search form for the dance style and event types fields:
<div >
<%= f.label "Dance style", class: "form-label" %>
<%= f.select(:dance_styles_id_eq, DanceStyle.all.pluck(:name, :id), { :include_blank => "All dance styles" }, { class: "form-select", id: "select-dancestyle", multiple: true, placeholder: "Any dance style" }) %>
</div>
<div >
<%= f.label "Event Type", class: "form-label" %>
<%= f.select :event_type_id_eq, EventType.all.pluck(:name, :id), { :include_blank => "All event types" }, { id: "select-artist", placeholder: "Any event type", class: "form-select" } %>
</div>
Here's my Event controller index:
def index
if params[:q]
params[:q][:combinator] = "and"
params[:q][:groupings] = []
split_geo = params[:q][:address_or_city_or_state_or_country_or_continent_cont_all].split(/(,\s) /)
split_geo.map! do |a|
I18n.transliterate a
end
split_geo.each_with_index do |word, index|
params[:q][:groupings][index] = { address_or_city_or_state_or_country_or_continent_cont_all: word }
end
end
@q = Event.ransack(params[:q])
@events = @q.result(distinct: true)
.where(event_status_id: 1)
end
end
Here's the full stack error I'm getting when I set the input fields to allow multiple and search multiple dance styles:
14:35:32 web.1 | Started GET "/events?q[name_cont]=&q[address_or_city_or_state_or_country_or_continent_cont_all]=&q[dance_styles_id_eq][]=&q[dance_styles_id_eq][]=5&q[dance_styles_id_eq][]=6&q[event_type_id_eq]=&q[event_month_eq]=&q[event_year_eq]=&commit=Search!" for ::1 at 2022-10-14 14:35:32 -0500
14:35:32 web.1 | Processing by EventsController#index as HTML
14:35:32 web.1 | Parameters: {"q"=>{"name_cont"=>"", "address_or_city_or_state_or_country_or_continent_cont_all"=>"", "dance_styles_id_eq"=>["", "5", "6"], "event_type_id_eq"=>"", "event_month_eq"=>"", "event_year_eq"=>""}, "commit"=>"Search!"}
14:35:32 web.1 | Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.0ms | Allocations: 2335)
14:35:32 web.1 |
14:35:32 web.1 |
14:35:32 web.1 |
14:35:32 web.1 | NoMethodError (undefined method `to_i' for ["", "5", "6"]:Array
14:35:32 web.1 | Did you mean? to_s
14:35:32 web.1 | to_a
14:35:32 web.1 | to_h):
14:35:32 web.1 |
14:35:32 web.1 | app/controllers/events_controller.rb:38:in `index'
How does the to_i
tie into this? I'm assuming this fix will need to be handled in my events controller.
CodePudding user response:
Not fully up on Ransack but have previously run into this sort of issue (to_i
being invoked on an Array
and not an actual Number
).
I believe this SO Q&A may help you: Rails multi-select getting undefined method `to_i'
As you may be able to tell from reading the above Q&A, the problem may be in your form field's name (not sure if that matters to Ransack and am not clear on your app's models, etc.).
See if altering f.select :dance_styles_id_eq
to f.select :dance_styles_ids
helps as noted in the linked Q&A. Please note that it may be f.select :dance_styles_id
as I am not fully up to snuff on Ransack and it's API. If I may oversimplify for a moment, a true Railsy form, would use the plural (dance_styles_ids
) to reference a has_many
association.
On other thing to note is that your array of dance style identifiers has an empty string, which you definitely do not want (found in this part of the error message to_i for ["", "5", "6"]:Array
).
Here's a link to an SO &A on removing blank elements from an array in ruby: How do I remove blank elements from an array?
Hope this can get you started and going in the right direction for the fix!
CodePudding user response:
Right name of the input is dance_styles_id_in
. It matches any values in array. But now you use dance_styles_id_eq
, replace it
And you also send empty string in params. To prevent it use include_hidden: false
option
<%= f.select(:dance_styles_id_in, DanceStyle.all.pluck(:name, :id), { include_blank: "All dance styles", include_hidden: false }, { class: "form-select", id: "select-dancestyle", multiple: true, placeholder: "Any dance style" }) %>