Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use ransacker? #36

Closed
lunks opened this issue Oct 25, 2011 · 16 comments
Closed

How to use ransacker? #36

lunks opened this issue Oct 25, 2011 · 16 comments

Comments

@lunks
Copy link

@lunks lunks commented Oct 25, 2011

I've got an ActiveRecord model with a scope and a ransacker defined like this:

  scope :by_country_state, lambda {|state|
    ddds = City.where(:country_state => state).map{|city| city.ddd}.uniq!
    where(:ddd => ddds)
  }
  ransacker :by_country_state

If I try to add f.text_field :by_country_state on the view, when I search I get ArgumentError (No valid predicate for by_country_state), if I try to add f.text_field :by_country_state_eq, I get:

TypeError (Cannot visit ActiveRecord::Associations::JoinDependency::JoinBase):
  app/models/telephone.rb:8:in `block in <class:Telephone>' 

Line 8 is the second line on my former blockquote.

I'm following this behavior from meta_search search_methods, so I might be taking the wrong approach, but I couldn't figure it out from the specs or the code. Could you help me, please?

@lunks
Copy link
Author

@lunks lunks commented Oct 26, 2011

Got working this way:

  ransacker :by_country_state, formatter: proc { |v|
    City.where(country_state: v).map{ |city| city.ddd }.uniq
    }, splat_param: true do |parent|
    parent.table[:ddd]
  end
@lunks lunks closed this Oct 26, 2011
@burlesona
Copy link

@burlesona burlesona commented Nov 19, 2012

Hey @lunks, since there is zero documentation for ransackers, would you be kind enough to explain what the heck your code is doing? What is v, where does it go, what is a formatter, what happens inside the block, etc etc etc. I really appreciate your help understanding what's going on here. Thanks!

@lunks
Copy link
Author

@lunks lunks commented Nov 19, 2012

Sure, let me refactor it a little bit so it is more clearer:

  ransacker :by_state, formatter: proc { |current_state|
    City.where(state: current_state).map{ |city| city.area_code}.uniq
    }, splat_param: true do |parent|
    parent.table[:area_code]
  end

What I'm basically doing is picking a State out of a drop down. Once one is selected, I use it to find all cities which are contained in that given state, find out their area codes, and use it to filter my current model (in this case, Call).

TL;DR
Given a state, find me all calls within that area, using its cities area codes.

Is that clearer?

@burlesona
Copy link

@burlesona burlesona commented Nov 19, 2012

Ok so, the ransacker takes the value that is dropped into your formatter proc, current_state, and then turns that into an array of unique area codes.

The rest confuses me still: splat param means multiple area codes will be used in a search?

And, how do the area codes end up in the block? That's what really is confusing me... I see you're telling the ransacker you want to search the area_code column on the parent table, but how does it know what you want to search for?

@lunks
Copy link
Author

@lunks lunks commented Nov 19, 2012

Not sure about splat_params. Perhaps it worked without it? I don't have access to the codebase anymore.

The ransacker creates something like a virtual attribute: I can then use f.text_field :by_state_in field and everything will work magically.

@burlesona
Copy link

@burlesona burlesona commented Nov 19, 2012

Yeah, the problem I'm having is a more complex query than just matching a string. If you don't mind, can you take a look here: #164

I've been working on this for days, and it feels like voodoo.

@burlesona
Copy link

@burlesona burlesona commented Nov 19, 2012

By the way, thank you so very much for responding to my cry for help here, it has been a nightmare trying to get answers to how this works, and unfortunately there isn't much documentation.

@lunks
Copy link
Author

@lunks lunks commented Nov 19, 2012

Not a problem at all. I've commented on it and ping the original repo owner. I'm not sure he's working on it and actively supporting it, though. Good luck!

@IgorDobryn
Copy link
Contributor

@IgorDobryn IgorDobryn commented Dec 9, 2013

Hey guys, is there a way to add sql HAVING with ransacker?

@artm
Copy link
Contributor

@artm artm commented Dec 27, 2013

Since this issue is supposed to be the documentation of ransackers, here are some things left unclear:

  • What options do ransackers support (like that formatter)?
  • What happens with the block of a ransacker?
  • What is this parent that is yeilded into the block?
  • Can other things be yielded there somehow?
  • What is a ransacker conceptually, how should I think about it (because at the moment I'm confused)?
@garrettlancaster
Copy link

@garrettlancaster garrettlancaster commented Feb 11, 2014

+1 on some actual documentation here

@nikhgupta
Copy link

@nikhgupta nikhgupta commented Mar 12, 2014

Probably, my notes on this topic may help somebody, in future:
Custom Filters using ransacker in ActiveAdmin interfaces

@andrewroth
Copy link

@andrewroth andrewroth commented Mar 26, 2014

Why is it so hard just to use a scope? I very much identify with this: #164 (comment)

@dmitry
Copy link

@dmitry dmitry commented Aug 21, 2014

Looks like it's now possible out of the box: 72dd5d1

Just tried - works perfectly. Upgraded from meta_search without any issues.

Just update to latest master: gem 'ransack', github: 'activerecord-hackery/ransack'

@ckhung5
Copy link

@ckhung5 ckhung5 commented Apr 10, 2019

Hi..

This doesn't work

ransacker :by_items, formatter: proc { |v|
   Item.all
    }, splat_param: true do |parent|
    parent.table[:id]
  end

but this works

ransacker(:by_items, formatter: proc { |v|
     Item.all.map("Depending what you want to filter with v").map(&:id)
  }, splat_param:true )do |parent|
    parent.table[:id]
  end

The parrent.table[:id] is to render the Item that you filter with id. If you dont give an id, it will render an empty page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
9 participants
You can’t perform that action at this time.