【问题标题】:ROR + Ransack: FIlter results by range of numbers (age categories)ROR + Ransack:按数字范围(年龄类别)过滤结果
【发布时间】:2017-10-10 08:26:14
【问题描述】:

我正在尝试使用 Ransack 允许按年龄类别过滤条件。但是,我没有将年龄类别作为文章表的一部分,而是作为文章模型中的一种方法。我已经引用了这个其他的

我希望用户能够过滤带有 created_at 日期属于某个年龄类别的文章,但是,我似乎无法理解为什么根本没有呈现用于选择年龄类别的 options_for_select 列表。当我在rails控制台中检查时,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"...

【问题讨论】:

  • 您忘记了 =(等号)&lt;% f.select :age_group_in,#... %&gt; 应该是 &lt;%= f.select :age_group_in,#... %&gt;。您的 ransacker 可能还有其他问题,但这就是下拉菜单不呈现的原因。
  • @engineersmnky 对我很粗心。是的,我的 ransacker 语法有问题,因为我现在点击提交后出现上述错误。
  • 是的,我想,但我认为您可能也应该考虑一下您的逻辑。例如,您希望months_between 在什么时候大于 12,以及您希望您的第三个和第四个条件如何应用?现在months_between 的最大范围是 0-11(因为DateTime#month 将返回 1-12),第二个条件是 &lt;= 12,它始终为真。

标签: ruby-on-rails ruby ruby-on-rails-5 ransack


【解决方案1】:

你可以像这样创建一个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。这个答案假定postgres 如果你使用类似MSSQL 的东西,那么CASE 药水被简化为DATEDIFF(m,#{parent.table[:created_at]},GETDATE())

这缺乏日常准确性,但我认为它足够接近您的使用

【讨论】:

  • 我得到 2 个错误:1)语法错误:意外的输入结束,2(在编辑器本身的 EOF 之前的任何地方都找不到字符串“SQL”。
  • @diana 你确定你使用了我发布的内容,包括Arel.sql(query) 之前的SQL?在this Gist中工作正常@
  • 是的.. 在我再次复制和粘贴后它现在可以工作了,但奇怪的是这正在发生...screenshots.firefox.com/qYIxobvqy3jy49D8/ide.c9.io,我现在收到 ActiveRecord::StatementInvalid 错误 --> PG::SyntaxError : 错误: "Arel" 第 1 行或附近的语法错误: ...year', CURRENT_DATE) - DATE_PART('year', #
  • @diana 那是我的错误,现在更新了。您也可以将parent.table[:created_at] 更改为articles.created_at
猜你喜欢
  • 2021-10-22
  • 2019-10-31
  • 1970-01-01
  • 1970-01-01
  • 2018-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多