aranhaqg
aranhaqg

Reputation: 99

How can I use Ransack gem to search a date and another value types in multiple columns?

In my view I wanna search a value in a date column and a string column with the same text_field using Ransack gem.

I've already known how to search multiple strings columns with just one text field, but searching a date column and a string column has been proving to be hard.

I tried something like this in the view:

<%= f.search_field :date_or_name_eq, { :class => "form-control", :placeholder => "Search..." } %>

And this in the controller:

@q = MyModel.ransack(params[:q])
@q.sorts = 'created_at desc' if @q.sorts.empty?
@my_model = @q.result().order(created_at: :desc).page(params[:page]).per(20).distinct

But that, doesn't work. It ignores the name column for searching. It only brings what it find in the date column. And I need something that work for search in theese two columns.

Can someone help me?

For pagination I use the Kaminari gem.

Upvotes: 4

Views: 2135

Answers (1)

Daniel Rikowski
Daniel Rikowski

Reputation: 72544

This is absolutely possible with Ransack. Perhaps your date input cannot be parsed (Time.zone.parse is used internally) or that parsed time doesn't actually match anything.

I tried this on my app, where I also use Ransack:

Ruby code:

Client.ransack(name_or_updated_at_eq: '1. Januar 2011').result()

Generated SQL:

SELECT "clients".* FROM "clients" WHERE 
    ("clients"."name" = '1. Januar 2011' OR "clients"."updated_at" = '2011-01-01 00:00:00')

(Note that Rails has no problem parsing the localized date)

The resulting Time instance contains also a time which is missing from the original query input. If the database column doesn't match the same time exactly Ransack returns no match. (With a pure date column this should work, though)

If that is actually the cause, you can use a custom ransacker:

In MyModel add:

ransacker :my_date_column, type: :date do
  Arel.sql('date(my_date_column)')
end

Depending on your database backend you might need a different syntax to cast the timestamp into a date. (e.g. try date_trunc('day', my_date_column) for PostgreSQL)

More details on Ransackers: https://github.com/activerecord-hackery/ransack/wiki/using-ransackers

Upvotes: 2

Related Questions