4

我想使用 ransack 为带有Users. 我有一个从出生日期计算年龄的小方法:

def age(dob)
  now = Time.now.utc.to_date
  now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end

这适用于正常显示 ( as in age(@user.date_of_birth))

但是当使用 search_form_for 我不能做同样的事情:

<%= search_form_for @search, url: search_users_path, method: :post do |f| %>
    <div class="field">
        <%= f.label :date_of_birth_gteq, "Age between" %>
        <%= f.text_field :date_of_birth_gteq %>
        <%= f.label :date_of_birth_gteq, "and" %>
        <%= f.text_field :date_of_birth_lteq %>
    </div>
<div class="actions"><%= f.submit "Search" %></div>
 <% end %>

我的问题是:如何在搜索中使用年龄而不是出生日期?

4

3 回答 3

5

添加如下所示的范围以查找给定年龄的日期。

scope :age_between, lambda{|from_age, to_age|
  if from_age.present? and to_age.present?
    where( :date_of_birth =>  (Date.today - to_age.to_i.year)..(Date.today - from_age.to_i.year) )
  end
}

对于洗劫语法:

ransacker :age, :formatter => proc {|v| Date.today - v.to_i.year} do |parent|
  parent.table[:date_of_birth]
end   

在视图中

<%= f.text_field :age_gteq %>
于 2012-12-24T13:06:47.903 回答
2

我个人并不了解 ransacker 并尝试使用 ransacker 但找不到任何可以检查传入谓词的东西。因此我认为最好使用范围来执行此操作。

def self.age_lteq(age)
  start_birth_year = Date.today.year - age
  where('date_of_birth >= ?', Date.new(start_birth_year))
end

def self.age_gteq(age)
  birth_year = Date.today.year - age
  end_of_birth_year = Date.new(birth_year + 1) - 1
  where('date_of_birth <= ?', end_of_birth_year)
end

private

def self.ransackable_scopes(auth_object = nil)
  %i(age_lteq age_gteq)
end

# In views just do the following (ransack default grouping queries is by AND)
# https://github.com/activerecord-hackery/ransack#grouping-queries-by-or-instead-of-and
<%= f.input :age_lteq %>
<%= f.input :age_gteq %>

@siddick 的回答很酷,但行为的逻辑lteq就像gtgteq行为一样lt。我自己最近开始使用 ruby​​ 和 rails。所以,如果我做错了什么,请告诉我。:) 谢谢!

于 2015-05-26T02:14:06.170 回答
1

只是@siddick 答案的更新(效果很好)。您现在需要将 ransack 提供的范围列入白名单。对于@siddick 的回答,您需要这样做:

def self.ransackable_scopes(auth_object = nil)
  %i(age_between)
end

有关更多信息,请参阅文档 - https://github.com/activerecord-hackery/ransack#using-scopesclass-methods

于 2014-09-26T09:15:39.247 回答