2015-10-06 89 views
1

我正在更新具有ActiveAdmin組件(ActiveAdmin 0.6,Ruby 1.9.3和Rails 3.2)的舊ruby \ rails應用程序。用戶已經請求過濾器來搜索給定模型中的所有字段。我不認爲這是實際的,因爲你不能搜索日期或數字值「a」,所以我已經妥協了只用過濾器搜索文本。ActiveAdmin從動態模型屬性中自定義過濾器

查看了ActiveAdmin文檔後,您可以使用屬性之間的「」創建多個屬性的過濾器。所以,如果我想搜索「情況」或「accident_type」屬性,我會使用下面的過濾:如果我用這個語法過濾器工作正常

filter :circumstances_or_accident_type, :as => :string, label: "Search All Text Fields" 

我現在想找到所有的字符串\文本屬性由我使用此代碼(也有這樣做的可能是整潔的方式,但它的工作原理)過濾器的屬性創建:

xfilter_text = "" 
Notification.columns.each do |xfield| 
    if xfield.type == :string or xfield.type == :text 
    if xfilter_text.length == 0 
     xfilter_text = xfield.name 
    else 
     xfilter_text << "_or_" 
     xfilter_text << xfield.name 
    end 
    end 
end 

我用導致硬編碼的值到這給了我下面的過濾器(是的,在該模式中的一些屬性):

filter :circumstances_or_accident_type_or_author_type_or_location_or_immediate_action_or_injury_details_or_outcome_type_or_investigation_findings_or_action_to_prevent_recurrence_or_building_or_classification_or_manager_email_or_manager_name_or_current_stage_or_injured_last_name_or_injured_first_name_or_injured_gender_or_injured_address_or_injured_home_telephone_or_injured_work_status_or_injured_job_title_or_injured_working_pattern_or_injured_email_or_riddor_document_or_body_part_or_kind_of_accident_or_injury_type_or_service_or_team_or_defects_or_witness_details_or_location_details_or_hse_reference_number_or_riddor_category_or_address_or_details_of_treatment_or_processor_actions_or_business_unit_or_other_author_type_or_lost_time_details_or_changed_by_or_details_of_hospital_treatment, :as => :string, label: "Search All Text Fields" 

我測試了這一點,它的工作。迄今爲止都很好。我可以將它留在這裏,但我想確保代碼是自我維護的,因此模型中的任何更改都不需要更改自定義過濾器。這是我遇到的問題。我想改變硬編碼的屬性來使用以某種方式創建過濾器屬性的代碼的結果。這樣的事情:

filter :get_filter, :as => :string, label: "Search All Text Fields" 

def get_filter 
    xfilter_text = "" 
    Notification.columns.each do |xfield| 
    if xfield.type == :string or xfield.type == :text 
     if xfilter_text.length == 0 
     xfilter_text = xfield.name 
     else 
     xfilter_text << "_or_" 
     xfilter_text << xfield.name 
     end 
    end 
    return xfilter 
    end 
end 

我希望我會需要的東西,檢查屬性返回,否則過濾器將失敗。我可以補充說,一旦我得到的代碼工作。

感謝任何幫助或建議。

+0

您是否將ActiveAdmin更新至0.6以上?也就是說,您是否在尋找一種搜索或元搜索解決方案? – ahmacleod

+0

不,我不想更新ActiveAdmin。我正在尋找一種解決方案,可以讓我隨時構建垃圾過濾器。 –

回答

2

我傾向於採用生成查詢的混亂業務並將其委託給模型,使用它自己的作用域/類方法。然後,您只需告知MetaSearch/Ransack(取決於您的ActiveAdmin版本)它可以搜索該範圍,並且可以將其添加爲過濾器。

對於獎勵積分,您可以將搜索方法放到您可以納入任何模型的關注點中。

應用程序/管理/ notifications.rb

filter :containing_text, as: :string, label: 'Text Search:' 

應用程序/模型/ notification.rb裏

# for MetaSearch 
# search_methods :containing_text 

# for Ransack 
def self.ransackable_scopes(_opts) 
    [:containing_text] 
end 

# this could be dropped into a concern as-is 
def self.containing_text(query) 
    # select text-type columns 
    cols = columns.select { |c| [:string, :text].include?(c.type) } 

    # generate query fragment 
    fragment = cols.map { |c| "#{ table_name }.#{ c.name } LIKE ?" } 
       .join(' OR ') 

    # execute sanitized query 
    where(fragment, *Array.new(cols.size, "%#{ query }%")) 
end 

###編輯由OP ###

我以前從未用過擔心,所以最終找出瞭如何得到它工作會有:

1)關注路徑添加到您的application.rb中

配置/應用。RB

class Application < Rails::Application 
    config.autoload_paths += %W(#{config.root}/app/models/concerns) 
end 

2)添加包括所創建的關注檢索的關心和方法調用到notifcation模型

應用程序/模型/ notification.rb裏

include Searchable 
search_methods :containing_text 

3) :

/app/models/concerns/searchable.rb

module Searchable 
    extend ActiveSupport::Concern 
    module ClassMethods 
    def self.containing_text(query) 
     # select text-type columns (string and text) 
     cols = columns.select { |c| [:string, :text].include?(c.type) } 
     # generate query fragment 
     fragment = cols.map { |c| "#{ table_name }.#{ c.name } LIKE ?" } 

        .join(' OR ') 
     # execute sanitized query 
     where(fragment, *Array.new(cols.size, "%#{ query }%")) 
    end 
    end 
end 

然後,這似乎工作。我可能應該將可搜索的內容重新命名爲更好的內容,但它可行。

+0

我會看看這個,當我有時更新帖子。謝謝。 –

+0

是的,這是一種享受,非常感謝ahmacleod。我不能在一個問題上工作,但我不關心這個問題; o) –

+0

發揮了擔憂,並最終得到它的工作。更新該帖子以向其他人顯示未使用過的人。 –