Rails&Ransack - 根据模型中的定义进行排序/搜索

ben*_*bwd 6 ruby-on-rails ruby-on-rails-3.2 ransack

比方说,我有一个带start_date和的事件length(作为表示天数的整数).

在这个模型中,我定义end_datestart_date + length.days很简单的,你会想到:

def end_date
  start_date + length.days
end
Run Code Online (Sandbox Code Playgroud)

一切都可以在模板中正常工作,我可以用它event.end_date来显示开始日期加上多少天长度设置为,但是,我现在想要使用Ransack在结束日期之前订购事件.

start_date看起来像这样的排序链接:<%= sort_link @q, :start_date, "Start" %>

如果我为end_date(<%= sort_link @q, :end_date, "End" %>)尝试相同,它很遗憾地失败,因为我认为它正在寻找end_date表中的列而没有找到它.

我只是愚蠢,还是我想做一些Ransack根本不做的事情?

ben*_*bwd 10

只是为了任何想要了解我是如何做到这一点的人的利益:

在我定义end_date的模型中

def end_date
  start_date + length.days
end
Run Code Online (Sandbox Code Playgroud)

然后我为:end_date添加了'rankingacker'方法

ransacker :end_date do |r|
   Arel::Nodes::SqlLiteral.new("DATE_ADD(`events`.`start_date`, INTERVAL `events`.`length` DAY)")
end
Run Code Online (Sandbox Code Playgroud)

老实说,我不知道这是否是执行上述条款的最佳/正确方法,但我对SQL比熟悉Ruby/Rails更熟悉,所以它对我来说非常开放.

有效地做的是创建一个SQL,它通过与end_date相同的定义来命令查询(start_date + length)

我现在可以在模板中使用以下代码进行排序链接(允许Ransacker处理ASC/DESC而不干扰wil_paginate等):

<%= sort_link @q, :end_date, "Event End Date" %>

当您单击该链接时,您将获得以下行的查询:

SELECT DISTINCT events.* FROM events ORDER BY DATE_ADD(events.start_date, INTERVAL events.length DAY) DESC LIMIT 30 OFFSET 0 - 所有由Ransacker在表格中的列上创建和处理的内容甚至不存在!

再一次,一个快速的免责声明,我已经学习Rails和Ruby大约2周了,来自PHP的背景,所以我不是专家,这可能是非常低效或者可能有更好的'轨道方式'我根本就不知道.