ROR + Ransack:根据数字范围(年龄类别)筛选结果
我试图按照使用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"...
您可以创建一个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())
。
这种缺乏日常的准确性,但我认为这是为您的使用足够接近
我得到2错误:1)语法错误:意外的输入结束,2(在编辑器本身的EOF之前的任何地方都找不到字符串“SQL” – doyz
@diana是否确实使用了我发布的内容,包括'Arel.sql(query)'之前的SQL'?在[这个Gist](https://repl.it/MZUM/1) – engineersmnky
是的,它可以正常工作。现在,我复制并粘贴后,但奇怪的是,正在发生...... https://screenshots.firefox。 com/qYIxobvqy3jy49D8/ide.c9.io,我现在得到一个ActiveRecord :: StatementInvalid错误 - > PG :: SyntaxError:ERROR:语法错误处于或接近“Arel” LINE 1:... year',CURRENT_DATE) - DATE_PART('year',#
你忘了'='(等号)''应该是' '。 ''ransacker'可能还有其他问题,但这就是为什么下拉不能渲染。 – engineersmnky
@engineersmnky,这是粗心的我。是的,我的ransacker语法存在问题,因为我现在在单击提交后出现上述错误。 – doyz
是的,我认为,但我认为你应该考虑一下你的逻辑。例如,您希望“months_between”大于12的时间点以及您如何期望第三个和第四个条件适用?现在'months_between'的最大范围是0-11(因为DateTime#month将返回1-12),第二个条件是始终为真的 engineersmnky