2017-10-10 131 views
0

我試圖按照使用Ransack的年齡類別來允許篩選條件。但是,我沒有將年齡段作爲文章表的一部分,而是作爲文章模型中的一種方法。我已經參考了這個ROR + Ransack:根據數字範圍(年齡類別)篩選結果

我希望用戶能夠過濾具有屬於年齡段的created_at日期的文章,但是,我似乎無法理解爲什麼選擇年齡段的options_for_select列表根本沒有被呈現。當我檢查軌道控制檯時,div標記之間沒有內容。

但是,呈現了options_from_collection_for_select的下拉列表。

模式:

create_table "articles", force: :cascade do |t| 
    t.string "title" 
    t.text "description" 
    t.bigint "user_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    end 

browse.html.erb

<div class="form-group"> 
    <div class ="row"> 
    <div class="col-md-6 col-sm-6 col-xs-6"> 
     <%= f.select :categories_name_cont, options_from_collection_for_select(Category.all, "id", "name", @q.categories_name_eq), 
                      { :prompt => "Any Category" }, 
                      { class: "form-control" } %> 
    </div> 
    <div class="col-md-6 col-sm-6 col-xs-6"> 
     <% f.select :age_group_in, options_for_select([["more than 1 year ago", "more than 1 year ago"], 
                ["less than 1 year ago", "less than 1 year ago"], 
                ["less than 3 months ago", "less than 3 months ago"], 
                ["less than 1 month ago", "less than 1 month ago"]]), 
                { :prompt => "Any Age Group" }, 
                { class: "form-control" } %> 
    </div> 
    </div> 
</div> 

文章控制器

def browse 
    @q = Article.ransack(params[:q]) 
    @articles_morefilter = @q.result.includes(:categories, :users) 
end 

模型:article.rb

def age_group 
    months_between = Date.today.month - self.created_at.month 
    if months_between > 12 
     "more than 1 year ago" 
    elsif months_between <= 12 
     "less than 1 year ago" 
    elsif months_between <= 3 
     "less than 3 months ago" 
    elsif months_between <= 1 
     "less than 1 month ago" 
    end 
    end 

ransacker :age_group, :formatter => proc {|v| Date.today.month - v.created_at.month} do |parent| 
    parent.table[:created_at] 
end 

編輯:我固定它通過添加=之後<%呈現字段。我現在正在得到一個新的錯誤,似乎Ransacker語法存在問題。

PG::InvalidDatetimeFormat: ERROR: invalid input syntax for type timestamp: "less than 1 month ago" 
LINE 1: ...name" ILIKE '%1%' AND "articles"."created_at" IN ('less than... 

當我測試改變parent.table[:created_at]parent.table[:age_group],我得到這個錯誤,而不是:

PG::UndefinedColumn: ERROR: column articles.age_group does not exist 
LINE 1: ...ry_id" WHERE ("categories"."name" ILIKE '%3%' AND "articles"... 
+0

你忘了'='(等號)'<%f.select:age_group_in,#...%>'應該是' <%= f.select:age_group_in,#...%>'。 ''ransacker'可能還有其他問題,但這就是爲什麼下拉不能渲染。 – engineersmnky

+0

@engineersmnky,這是粗心的我。是的,我的ransacker語法存在問題,因爲我現在在單擊提交後出現上述錯誤。 – doyz

+0

是的,我認爲,但我認爲你應該考慮一下你的邏輯。例如,您希望「months_between」大於12的時間點以及您如何期望第三個和第四個條件適用?現在'months_between'的最大範圍是0-11(因爲DateTime#month將返回1-12),第二個條件是始終爲真的<= 12。 – engineersmnky

回答

0

您可以創建一個ransacker像這樣

class Article < ApplicationRecord 

    ransacker :age_group do |parent| 
    query= <<-SQL 
     CASE ((DATE_PART('year', CURRENT_DATE) - DATE_PART('year', #{parent.table[:created_at].to_sql})) * 12 + 
      (DATE_PART('month', CURRENT_DATE) - DATE_PART('month', #{parent.table[:created_at].to_sql}))) 
     WHEN 0,1 THEN "less than 1 month ago" 
     WHEN 2,3 THEN "less than 3 months ago" 
     WHEN 4,5,6,7,8,9,10,11,12 THEN "less than 1 year ago" 
     ELSE "more than 1 year ago" 
     END 
    SQL 
    Arel.sql(query) 
    end 

,然後在視圖中更改:age_group_in:age_group_eq。如果您使用類似MSSQL之類的東西,則此答案假定爲postgres,那麼CASE藥水簡化爲DATEDIFF(m,#{parent.table[:created_at]},GETDATE())

這種缺乏日常的準確性,但我認爲這是爲您的使用足夠接近

+0

我得到2錯誤:1)語法錯誤:意外的輸入結束,2(在編輯器本身的EOF之前的任何地方都找不到字符串「SQL」 – doyz

+0

@diana是否確實使用了我發佈的內容,包括'Arel.sql(query)'之前的SQL'?在[這個Gist](https://repl.it/MZUM/1) – engineersmnky

+0

是的,它可以正常工作。現在,我複製並粘貼後,但奇怪的是,正在發生...... https://screenshots.firefox。 com/qYIxobvqy3jy49D8/ide.c9.io,我現在得到一個ActiveRecord :: StatementInvalid錯誤 - > PG :: SyntaxError:ERROR:語法錯誤處於或接近「Arel」 LINE 1:... year',CURRENT_DATE) - DATE_PART('year',# doyz