【问题标题】:search for users age based on date of birth根据出生日期搜索用户年龄
【发布时间】:2013-08-16 16:38:24
【问题描述】:

我无法理解如何根据用户的出生日期对其年龄进行范围搜索。我的数据库仅存储用户 dob。我希望访问者使用高级搜索表单并执行年龄搜索,例如“18-23”、“28-36”等。

我尝试了一些方法,但似乎都没有。我将范围添加到用户模型、定义最小和最大年龄,以及另一种没有成功的解决方案。也许我得到了一些正确的代码,但没有执行另一部分。我不知道。如果有人可以指导我正确的方向,那就太好了,这样我就可以学习了。

当我根据所选年龄执行搜索时,它会返回所有用户。

搜索模型:

attr_accessible :age, :children, :ethnicity, :career, :gender, :religion, :zip_code, :birthday, :max_age, :min_age, :youngest_age, :oldest_age

  def users
    @users ||= find_users
  end

    private

  def find_users
    users = User.order(:id)
    users = users.where(gender: gender) if gender.present?
       users = users.where(zip_code: zip_code) if zip_code.present?
       users = users.where(children: children) if children.present?
       users = users.where(religion: religion) if religion.present?
       users = users.where(ethnicity: ethnicity) if ethnicity.present?
       users = users.where("birthday >= ? AND birthday <= ?", 80.years.ago + 1.day, 18.years.ago)


       users
  end
end

搜索表单:

<%= select(@object, :youngest_age, (18..75).to_a) %> to <%= select(@object, :oldest_age, (18..75).to_a) %>

【问题讨论】:

    标签: ruby-on-rails search date


    【解决方案1】:

    应该这样做:

    # view
    <%= select @object, :min_age, (18..75).to_a %>
    to
    <%= select @object, :max_age, (18..75).to_a %>
    
    # controller
    def show
      @search = Search.find(params[:id])
      @users = @search.users
    end
    
    # Search model
    def find_users
      users = User.order(:id)
      users = users.where(gender: gender) if gender.present?
      users = users.where(zip_code: zip_code) if zip_code.present?
      users = users.where(children: children) if children.present?
      users = users.where(religion: religion) if religion.present?
      users = users.where(ethnicity: ethnicity) if ethnicity.present?
    
      if min_age.present? && max_age.present?
        min = [ min_age, max_age ].min
        max = [ min_age, max_age ].max
        min_date = Date.today - min.years
        max_date = Date.today - max.years
        users = users.where("birthday BETWEEN ? AND ?", max_date, min_date)
      end
      users
    end
    

    【讨论】:

    • 我正在将搜索保存到数据库中,这就是模型存在的原因。
    • 那么你可以使用搜索方法的代码作为搜索模型上的find_users方法——我刚刚更新了我的答案@pwz2000
    • 我收到了一个未定义的局部变量或方法 min_age,它指向来自行 if min_age.present ? &amp;&amp; max_age.present? 的搜索模型。它还从 def users @users ||=find_users 下的搜索模型和 def show @users = @search.users 的搜索控制器显示。
    • 您必须使这些属性可访问。您的搜索模型是否具有这 2 个属性(min_age 和 max_age)?
    • 还要记住users.where("birthday BETWEEN ? AND ?", max_date, min_date)可以写成users.where(birthday: min_date..max_date)
    【解决方案2】:

    您需要将两个参数从搜索表单传回控制器。我假设这些将是params[:youngest_age]params[:oldest_age]。我还假设那些将是整数(例如:params[:youngest_age] = 18

    youngest_age = params[:youngest_age].years
    oldest_age = params[:oldest_age].years
    
    User.where("birthday >= ? AND birthday <= ?", Date.today - youngest_age, Date.today - oldest_age)
    

    【讨论】:

    • 我收到指向搜索模型的相同错误“未定义的局部变量或方法‘min_age’”。我已经用我所拥有的更新了我的代码。
    • 听起来您正在处理模型/控制器中的一个问题,该问题与获取给定年龄范围内的用户是分开的。呈现表单(新操作)或提交表单时是否出现错误?
    【解决方案3】:

    您的代码中的此方法似乎存在错误:

    def find_users
      users = User.order(:id)
      users = users.where(gender: gender) if gender.present?
      users = users.where(zip_code: zip_code) if zip_code.present?
      users = users.where(children: children) if children.present?
      users = users.where(religion: religion) if religion.present?
      users = users.where(ethnicity: ethnicity) if ethnicity.present?
      users = User.where("birthday >= ? AND birthday <= ?", 80.years.ago + 1.day, 18.years.ago)
      users
    end
    

    在倒数第二行,在返回用户之前,调用“User.where”而不是“users.where”。所以本质上你是在那个时候开始一个新的查询,而不是把所有的条件加在一起。

    【讨论】:

    • 切换到 users.where 不会改变任何东西。
    • 我可能只是数据库有问题。我已经在代码本身上工作了很长一段时间,没有人真正建议过我没有尝试过的任何东西。我唯一没有深入研究的部分是数据库中的数据。
    • 感谢您的协助。 Yoshiji 先生提供了一个有效的解决方案,我必须修复视图。
    【解决方案4】:

    修复find_users 方法的最后一个where 子句以使用users 关系,以便继续查询链而不是User 模型类,这有效地重置了查询范围。

    对于日期范围搜索,您的查询可以使用常规 ruby​​ 范围完全避免 SQL 字符串片段:

    用户模型:

    def self.with_age_range(year_range)
      today = Date.today
      where birthday: (today - year_range.max.years)..(today - year_range.min.years)
    end
    

    并调用如下:

    User.with_age_range 18..23
    

    或者在你的控制器中:

    @users = User.with_age_range params[:min_age]..params[:max_age]
    

    【讨论】:

    • 'Undefined method yeas for nil:NilClass' 使用您创建的代码的用户模型。特别是where birthday: (today - year_range.max.years)..(today - year_range.min.years)
    • 感谢MrYoshiji,我得到了答案。而且我还需要对视图做一个小修复。感谢发帖!
    猜你喜欢
    • 2013-10-31
    • 1970-01-01
    • 2014-04-04
    • 1970-01-01
    • 2013-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-12
    相关资源
    最近更新 更多