2015-06-27 20 views
4

我有一個交易模型,它具有名爲deal_info的json列。它實際上是一個JSON數組。在特定的json鍵上過濾ActiveAdmin和Postgresql json列

我正在使用活動管理員。

例如:

deal1.deal_info = [ { "modal_id": "4", "text1":"lorem" }, 
      { "modal_id": "6", "video2":"yonak" }, 
      { "modal_id": "9", "video2":"boom" } ] 
deal2.deal_info = [ { "modal_id": "10", "text1":"lorem" }, 
      { "modal_id": "11", "video2":"yonak" }, 
      { "modal_id": "11", "image4":"boom" } ] 

由於現在第一步我想有一個過濾器,這將使我基於這樣的事實,deal_info JSON列包括至少一個時間modal_id在過濾交易其包含的json之一。

它會使我在選擇下拉列表中選擇例如modal_id = 6,並將交易列表過濾爲僅顯示交易1(參見上面的示例)。

進一步的挑戰之一是我需要能夠刪除選擇下拉列表中的重複項,以便不會有多次相同的ID:這裏例如我不能有選擇= [4,6,9 ,10,11,11] ...每個modal_id只能出現一次。

我只找到this但它不適合我。安德烈的回答後

我現在的活動聯繫代號

ActiveAdmin.register Deal do 
    filter :modal_id, 
    as: :select 
    collection: deal_info.all.to_a.map ???? 
end 

編輯幫助推動,但(還)沒有解決問題

我加入這個代碼:

型號/ deal.rb

class Deal < ActiveRecord::Base 
    store_accessor :deal_info, :modal_id 
end 

# using https://stackoverflow.com/questions/14605710/filter-activeadmin-with-hstore?lq=1 
ransacker :modal_id do |parent| 
    Arel::Nodes::InfixOperation.new('->', parent.table[:deal_info], 'modal_id') 
end 

主動管理交易文件中

ActiveAdmin.register Deal do 
    filter :modal_id, 
    label: 'modal id', 
    as: :select, 
    collection: -> { Deal.all.pluck(:deal_info).flatten.map {|el| el['modal_id'] }.uniq } 

它似乎部分工作,但不完全。確實,它確實在下拉列表中顯示了正確的各種modal_id,並且它們很好地被重複刪除,但是當我在下拉列表中選擇其中一個時,並單擊右側的過濾器(過濾器邊欄)時,它會加載整個頁面再次沒有應用過濾器。

例如,在我的modal_id下拉列表中,我有ANY/4/5/8之間的選擇。如果我選擇modal_id 5,並在加載了所有交易(應該在modal_id = 5上進行過濾)的頁面時單擊FILTER按鈕,在側欄modal_id選擇下拉列表中,我看不到5,因爲我選擇了但是ANY。 5的值不是「KEPT」/「REMEMBERED」,它回到ANY值。 我不明白爲什麼。

EDIT 2

我對AA過濾器名稱變更爲 'EQ'

ActiveAdmin.register Deal do 
     filter :modal_id_eq, 
     label: 'modal id', 
     as: :select, 
     collection: -> { Deal.all.pluck(:deal_info).flatten.map {|el| el['modal_id'] }.uniq } 

但問題仍然是相同的。所以我查了一下,發現我的ransack腳本已經過時,並且使用Rails 4。2我有那麼現在我的代碼是

型號/ deal.rb

class Deal < ActiveRecord::Base 
    store_accessor :deal_info, :modal_id 
end 

# using https://stackoverflow.com/questions/14605710/filter-activeadmin-with-hstore?lq=1 
ransacker :modal_id do |parent| 
    Arel::Nodes::InfixOperation.new('->', parent.table[:deal_info], Arel::Nodes.build_quoted('modal_id')) 
end 

但現在我發現了以下錯誤來加build_quoted因爲在這裏展示https://github.com/activerecord-hackery/ransack/wiki/Using-Ransackers#3-search-for-a-key-in-an-hstore-column-in-this-example-searching-an-hstore-column-called-properties-for-records-containing-a-key-called-link_type

。我不知道這是由於Ransack,主動管理員或事實這個Ransack腳本爲hstore工作,但不是我的類型的json列或可能由於其他原因。

ActiveRecord::StatementInvalid at /admin/deals 

PG::UndefinedFunction: ERROR: operator does not exist: json = unknown 
LINE 1: ...OM "deals" WHERE "deals"."deal_info" -> 'modal_id' = '4' 

HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 
: SELECT COUNT(*) FROM "deals" WHERE "deals"."deal_info" -> 'modal_id' = '4': 
    activerecord (4.2.0) lib/active_record/connection_adapters/abstract_adapter.rb:455:in `translate_exception_class' 
    activerecord (4.2.0) lib/active_record/connection_adapters/abstract_adapter.rb:468:in `rescue in log' 
    activerecord (4.2.0) lib/active_record/connection_adapters/abstract_adapter.rb:466:in `log' 
    activerecord (4.2.0) lib/active_record/connection_adapters/postgresql_adapter.rb:592:in `exec_no_cache' 
    activerecord (4.2.0) lib/active_record/connection_adapters/postgresql_adapter.rb:584:in `execute_and_clear' 
    activerecord (4.2.0) lib/active_record/connection_adapters/postgresql/database_statements.rb:160:in `exec_query' 
    activerecord (4.2.0) lib/active_record/connection_adapters/abstract/database_statements.rb:336:in `select' 
    activerecord (4.2.0) lib/active_record/connection_adapters/abstract/database_statements.rb:32:in `select_all' 
    activerecord (4.2.0) lib/active_record/connection_adapters/abstract/query_cache.rb:68:in `block in select_all' 
    activerecord (4.2.0) lib/active_record/connection_adapters/abstract/query_cache.rb:83:in `cache_sql' 
    activerecord (4.2.0) lib/active_record/connection_adapters/abstract/query_cache.rb:68:in `select_all' 
    activerecord (4.2.0) lib/active_record/relation/calculations.rb:264:in `execute_simple_calculation' 
    activerecord (4.2.0) lib/active_record/relation/calculations.rb:221:in `perform_calculation' 
    activerecord (4.2.0) lib/active_record/relation/calculations.rb:127:in `calculate' 
    activerecord (4.2.0) lib/active_record/relation/calculations.rb:42:in `count' 
    () home/mathieup/.rvm/gems/[email protected]/bundler/gems/activeadmin-7aef260921d4/lib/active_admin/helpers/collection.rb:9:in `collection_size' 
    () home/mathieup/.rvm/gems/[email protected]/bundler/gems/activeadmin-7aef260921d4/lib/active_admin/views/components/scopes.rb:62:in `get_scope_count' 
    () home/mathieup/.rvm/gems/[email protected]/bundler/gems/activeadmin-7aef260921d4/lib/active_admin/views/components/scopes.rb:40:in `block (3 levels) in build_scope' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:31:in `block in build_tag' 
    arbre (1.0.2) lib/arbre/context.rb:92:in `with_current_arbre_element' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:49:in `with_current_arbre_element' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:26:in `build_tag' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:39:in `insert_tag' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:14:in `span' 
    () home/mathieup/.rvm/gems/[email protected]/bundler/gems/activeadmin-7aef260921d4/lib/active_admin/views/components/scopes.rb:39:in `block (2 levels) in build_scope' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:31:in `block in build_tag' 
    arbre (1.0.2) lib/arbre/context.rb:92:in `with_current_arbre_element' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:49:in `with_current_arbre_element' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:26:in `build_tag' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:39:in `insert_tag' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:14:in `a' 
    () home/mathieup/.rvm/gems/[email protected]/bundler/gems/activeadmin-7aef260921d4/lib/active_admin/views/components/scopes.rb:37:in `block in build_scope' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:31:in `block in build_tag' 
    arbre (1.0.2) lib/arbre/context.rb:92:in `with_current_arbre_element' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:49:in `with_current_arbre_element' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:26:in `build_tag' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:39:in `insert_tag' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:14:in `li' 
    () home/mathieup/.rvm/gems/[email protected]/bundler/gems/activeadmin-7aef260921d4/lib/active_admin/views/components/scopes.rb:33:in `build_scope' 
    () home/mathieup/.rvm/gems/[email protected]/bundler/gems/activeadmin-7aef260921d4/lib/active_admin/views/components/scopes.rb:26:in `block in build' 
    () home/mathieup/.rvm/gems/[email protected]/bundler/gems/activeadmin-7aef260921d4/lib/active_admin/views/components/scopes.rb:25:in `build' 
    arbre (1.0.2) lib/arbre/element/builder_methods.rb:30:in `block in build_tag' 
    arbre (1.0.2) lib/arbre/context.rb:92:in `with_current_arbre_element' 
+0

他們說你必須至少有postgres 9.3/9.4才能夠使用json(http://stackoverflow.com/questions/23098466/postgres-operators-for-json-data-type-using-rails- 4) –

+0

我有postgresql 9.4並在許多列中使用json – Mathieu

+0

'json'的' - >'運算符返回'json'(與'text'相反,就像'hstore'的運算符)&'json'不會與'text'(甚至不會與另一個'json')進行比較,這就是爲什麼你會得到最後一個錯誤。你應該使用' - >>'[operator](http://www.postgresql.org/docs/current/static/functions-json.html)。 – pozs

回答

2

檢查的東西沿着這些路線:

filter :modal_id_eq, # note _eq here 
    label: 'modal id', 
    as: :select, 
    collection: -> { Deal.all.pluck(:deal_info).flatten.map {|el| el['modal_id'] }.uniq } 
+0

謝謝!看來部分工作,但不完全。右下角的下拉列表使用了各種modal_id交易但是當我在下拉菜單中選擇其中的一個,然後點擊右側的過濾器(過濾器側欄)時,它會再次加載整個頁面而不應用過濾器。外匯,如果我選擇過濾modal_id = 5,證明它不適合我的是我看到所有的交易,並點擊「過濾器」後,頁面加載時,側欄內的modal_id選擇下拉,它沒有保留值5但回到任何。我會編輯我的問題。 – Mathieu

+0

我看到你已經添加了這個自定義搜索器,但你已經錯過了過濾器名稱中的小東西,我將編輯答案:)我不確定這是如何工作的,因爲我從來沒有用json做過,但讓我知道如果這改變了行爲 –

+0

你是對的,但它並沒有改變錯誤。但是,我發現我使用的ransack腳本已經過時,並且在Rails 4.2上,我不得不將它改爲使用名爲'build_quoted'的東西(參見本頁https://github.com/activerecord-hackery/ransack/wiki/使用-Ransackers#3搜尋 - 一鍵式-AN-hstore列式,這-例如,搜索-AN-hstore列所謂的屬性換含記錄 - -A-密鑰 - 被叫LINK_TYPE)。但現在得到一個新的錯誤。我編輯了我的問題。 – Mathieu

0

我用Rails 4.2和activeadmin(最新版本爲2015年9月11日),這工作得十分完美。

型號:

ransacker :card_code do |parent| 
    Arel::Nodes::InfixOperation.new(
     '->>', parent.table[:data], Arel::Nodes.build_quoted('card_code')) 
    end 

主動管理文件

filter :card_code_eq, label: 'Card code' 

請注意,我用' - >>' 的代替' - >'自後者返回一個需要被施放的JSON對象(我相信這是你遇到的問題)。請參閱PostgreSQL functions and operators獲取解釋。

希望自6月份以來,您解決了您的問題,但我認爲該解決方案可能對未來的其他人有用。

+0

感謝您的回答,我也感動了我。其實沒有不幸的是我離開這個未解決。我不知道如何,但我已經向前邁進,正在使用 - > - >。活動管理過濾器中的代碼:modal_id_eq, as::select, 集合: - > {Deal.all.pluck(:deal_info).flatten.map {| el | el ['modal_id']} .uniq}正在工作:它在活動的管理右側邊欄上顯示帶有值的下拉菜單。 – Mathieu

+0

但我的問題在於我認爲裏面有Ransacker,我認爲是因爲,當我在下拉列表中選擇一個模態_id(例如modal_id = 6)並提交搜索時,輸出爲0結果。但我知道我有deal_info列中有modal_id = 6的交易。就像deal17.deal_info = [{「modal_id」:「4」,「text1」:「lorem」}, {「modal_id」:「6」, 「video2」:「yonak」}, {「modal_id」:「9」,「video2」:「boom」}] – Mathieu