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?
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
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!
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?
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?
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.
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: https://github.com/ernie/ransack/issues/164
I've been working on this for days, and it feels like voodoo.
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.
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!
Hey guys, is there a way to add sql HAVING with ransacker?
Since this issue is supposed to be the documentation of ransackers, here are some things left unclear:
formatter)?parent that is yeilded into the block?+1 on some actual documentation here
Probably, my notes on this topic may help somebody, in future:
Custom Filters using ransacker in ActiveAdmin interfaces
Why is it so hard just to use a scope? I very much identify with this: https://github.com/activerecord-hackery/ransack/issues/164#issuecomment-19613313
For anyone else looking for a quick and dirty way to use a scope as a filter in Active Admin, see here:
https://github.com/CruGlobal/godchat/blob/master/app/admin/chat.rb#L10
https://github.com/CruGlobal/godchat/blob/master/config/initializers/active_admin_custom_filter.rb
https://github.com/CruGlobal/godchat/blob/master/app/admin/chat.rb#L66
https://github.com/CruGlobal/godchat/blob/master/app/models/chat.rb#L13
I used this method to create a regex filter in postgres.
Looks like it's now possible out of the box: https://github.com/activerecord-hackery/ransack/commit/72dd5d12d58919bf37199234cf13f9533f3b8cd5
Just tried - works perfectly. Upgraded from meta_search without any issues.
Just update to latest master: gem 'ransack', github: 'activerecord-hackery/ransack'
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.
Most helpful comment
Since this issue is supposed to be the documentation of ransackers, here are some things left unclear:
formatter)?parentthat is yeilded into the block?