简体   繁体   中英

Custom ActiveAdmin filter for Date Range

I need to create a custom ActiveAdmin filter for a Date Range which belongs to another resource. I want to filter a list of users by a date range of when they completed a survey.

I've declared a custom filter in the ActiveAdmin DSL like so:

filter :by_date_completed, label: 'By Date Completed', as: :date_range

This makes me a nice date range in active admin to restrict my users by. All good.

I haven't been able to find much documentation on how to do this but in my user model I've tried to create a ransacker to handle the filter.

ransacker :by_date_completed, {
    formatter: proc { |start_date, end_date|

        time_range = start_date..end_date
        users = User.joins(:surveys).where(surveys: { updated_at: time_range})

        users = users.map(&:id)
        users.present? ? users : nil
        }, 
    callable: proc { |parent|
    parent.table[:id]
    }
}  

But ActiveAdmin passes the date ranges to the filter one at a time and so I can't get a range to search by?

What am I meant to do in this scenario? Am I going about the whole problem in the wrong way?

I think you don't need a custom ransacker for that. You can filter a cross associations.

This should work for you:

filter :surveys_updated_at, label: 'By Date Completed', as: :date_range

What you do is not, how a ransacker should work. I know it's a common google result, but it's wrong.

  1. The ransacker don't receive both dates at once in ActiveAdmin. The ransacker will called with a by_date_completed_gteq and a by_date_completed_lteq .

  2. A ransacker formatter is only to format the input value. Convert a String into a Int for example.

  3. The block / the callable proc of the ransacker needs to return a Arel / SQL string which is placed in the DB query.

A abstract ransacker example:

ransacker :foo do
  "ransacker sql code"
end

"SELECT * FROM bar WHERE 'ransacker sql code' = <input>"

Your ransack should look like this:

ransacker :by_date_completed do
  "surveys.updated_at"
end

This should end up in a query like:

"SELECT * FROM users WHERE surveys.updated_at >= START_DATE AND surveys.updated_at <= END_DATE"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM