Search code examples
ruby-on-rails-4ransack

How does ransack search works on an array list?


I am using Rails 4.2.5, Ruby 2.2, ransack. I am trying to implement search functionality using Ransack. I have something like:

emails = ["abc@abc.com", "a@a.com", "b@b.com"]
users_list = emails.map{|a| User.where(email: a).first}
checked_in_users = Kaminari.paginate_array(users_list)

This gives me proper list of users in the page. But if I want to search by email, what should I do ?

@q = checked_in_users.ransack params[:q]

This gives me:

"NoMethodError (undefined method `ransack' for #<Array"

HAML code:

= search_form_for [@q], url: users_path(some_id: id) do |form|
  = form.text_field :user_name_or_user_email_cont, placeholder: 'Name or email', class: 'form-control'

What would be the correct way to do it with ransack ?


Solution

  • If you want to search the entire list of users, you could do something like this:

    @q = User.ransack(params[:q])
    @users = @q.result.page(params[:page])
    

    You want to call ransack on your model prior to adding pagination. Once you have the ransack result, you can add pagination. This section of the documentation shows you how to handle pagination with ransack. In its most basic form, this is how you can use ransack.


    Also, it looks like you have some odd code in your example. Apologies if I'm misunderstanding what you're trying to do.

    When you call emails.map{|a| User.where(email: a).first}, you're making a where query 3 times in this case and returning an array of 3 models. Ransack won't operate on that array.

    I would change it to something like this in your case:

    emails = ["abc@abc.com", "a@a.com", "b@b.com"]
    @q = User.where(email: emails).ransack(params[:q])
    @checked_in_users = @q.result.page(params[:page])
    

    Just know that you'd be searching from an array of users with emails of "abc@abc.com", "a@a.com", and "b@b.com". If you search with your ransack form for "bob@example.com", you wouldn't get any search results. This may not be what you want.