Reputation: 307
I'm trying to write a custom method on an ActiveAdmin Users model. It's my understanding that I have to use ransacker for this.
What I'd like happen is have a select with the following that shows up in the UI drop downs like this:
Aug 2010-Aug 2011
Aug 2011-Aug 2012
Aug 2012-Aug 2013
Aug 2013-Aug 2014
Aug 2014-Aug 2015
Aug 2015-Aug 2016
Here are my tables where I need to grab the information from.
Users
------
id (int)
school_participants
-------------------
user_id (int)
start_date (datetime)
SchoolParticipant belongs to a user, a user has many school_participants.
I initially tried doing something like this in ActiveAdmin filter
filter :participant_schools_start_date, :label => "School Year", :as => :select, :collection => [['2010', '2010-08-15'], ['2011', '2013-08-15']]
Just to see what we get in the forms, but I need a way to pass a range in the select fields, but apparently, you can only pass one value at a time. The first element (2010) in this array gets shown in the UI and the second element (2010-08-15) is what gets passed as the value.
Basically I'm trying to query between these ranges
**ON Selection in a drop down** **Query I want**
Aug 2010-Aug 2012 a query between 2010-08-15 to 2011-08-15
Aug 2011-Aug 2012 2011-08-15 to 2012-08-15
Aug 2012-Aug 2013 2012-08-15 to 2013-08-15
Aug 2013-Aug 2014 2013-08-15 to 2014-08-15
Aug 2014-Aug 2015 2014-08-15 to 2015-08-15
Aug 2015-Aug 2016 2015-08-15 to 2016-08-15
I tried to play with procs and lambdas using some resources I found like this one
http://nikhgupta.com/code/activeadmin/custom-filters-using-ransacker-in-activeadmin-interfaces
and
http://cavewall.jaguardesignstudio.com/2014/05/01/activeadmin-filters-with-ransack/
Any thought? Not sure how to make it work.
Upvotes: 4
Views: 3346
Reputation: 13
A solution would be to provide a value in the filter which should be converted to the date range:
filter :school_participants_schoolyear_in, as: :select, collection: %w[Aug 2013-Aug 2014 Aug 2014-Aug 2015 Aug 2015-Aug 2016 Aug 2016-Aug 2017]
And then convert that value in the ransacker (defined on the school participant model):
ransacker :schoolyear,
formatter: proc { |range_string|
dates = range_string.split('-').map{|d| (Date.parse(d) + 15.days).to_date}
date_range = dates.first...dates.last
results = SchoolParticipants.where(start_date: date_range).pluck(:id)
results.present? ? results : nil
}, splat_params: true do |parent|
parent.table[:id]
end
It will result in an extra query to find the ids of the SchoolParticipants so it can insert where school_participants.id IN ([all ids of relevant school participants]) in every scope query.
Upvotes: 1