1

我正在尝试使用 ransack 按年龄过滤结果,但 ransack 给了我一个未定义的方法错误。我的数据库中有用户 DOB,在我的用户模型中,我有一个计算用户年龄的年龄方法。它工作得很好,我可以这样称呼用户年龄:

@user = User.find(1)
@user.age

现在进行搜查,我的控制器中有以下内容:

  def index
   @search = User.search(params[:q])
   @users = @search.result
  end

在我看来,我有:

<%= search_form_for @search do |f| %>
    <%= f.label :age_gteq, "Ages:" %> <%= f.text_field :age_gteq %>
    <%= f.label :age_lteq, "to" %> <%= f.text_field :age_lteq %>
    <%=f.submit "Filter", class: "button" %>
<% end %>

这是我得到的错误:

undefined method `age_gteq' for Ransack::Search<class: User, base: Grouping <combinator: and>>:Ransack::Search

我相信我会得到同样的错误age_lteq

4

1 回答 1

3

据我所知,它不起作用,因为目前 Ransack 仅适用于数据库列。最后 Ransack 只是一个复杂的 SQL 查询生成器。

想想这个例子:

User.where('age >= ?', 30)

SQL 查询会是什么样子?

SELECT * FROM user WHERE age >= 30

即使 Ransack 会在正常的非数据库属性上处理此类条件,SQL 仍然是错误的。(因为没有age专栏)

一种解决方案是在表单中使用原始的出生日期列,并使用一些 Javascript 来允许用户输入年龄数字而不是日期。例如通过监听onsubmit事件并修改input' 的内容。

2014 年 1 月 8 日更新:

还有另一种可能使这项工作。将此添加到您的User模型中:

ransacker :age do
  Arel::Nodes::SqlLiteral.new(
     'DATE_PART('year', AGE(NOW(), date_of_birth_column))') 
  # Beware: PostgreSQL specific SQL!
end

“ransacker”需要返回一个 Arel 节点,该节点稍后将附加到 Ransack 生成的 Arel 节点。

这使您可以age_eq像使用常规数据库列一样使用所有其他 Ransack 谓词。

于 2013-04-06T12:05:11.180 回答