简体   繁体   中英

Filter for values OR IS NULL in activeadmin

Given I have two models:

class Post < ActiveRecord::Base
  belongs_to :district
end

class District < ActiveRecord::Base
  has_many :posts
end

I need to make a check_boxes filter in ActiveAdmin on Posts page for with ability for user to get posts that belong to some exact districts or does not belong to any districts at all.

Before ActiveAdmin changed MetaSearch to Ransack, that could be done with custom scope. And now I don't have any idea. When I do the following:

filter :district_id_null, as: :boolean
filter :district, as: :check_boxes

It makes condition WHERE district_id IN (1,2,3) AND district_id IS NULL (I need OR instead of AND). And when I do

filter :district, as: :check_boxes, collection: proc { District.unscoped.map { |x| [x.title, x.id] }.unshift ['Empty', 'null'] }

It makes condition WHERE district_id IN (0,1,2,3) (but in most SQL databases NULL is not 0).

I think something like this might work

class Post
    def self.ransack_with_or(search_params)
        params = search_params.deep_clone
        #check if we need OR
        if search_params.has_key?('district_id_in') && search_params.has_key?('district_id_null')
         params.delete('district_id_null')
         district_id_in = params.delete('district_id_in')
         #old behaviour without district_id_null and district_id_null attributes
         q = ransack_without_or(params)
         #here we're adding OR group 
         q.build_grouping({m: 'or', district_id_null: true, district_id_in: district_id_in}) 
        else
         #old behaviour we don't need OR
         q = ransack_without_or(params)
        end
        q
       end

       #wrapping ransack method 
       class << self
         alias_method_chain :ransack, :or
       end
    end

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