【问题标题】:How to conditionally apply where clause in Rails?如何有条件地应用 Rails 中的 where 子句?
【发布时间】:2021-10-25 10:05:47
【问题描述】:

我有代码:

ApplyJob.includes(:job, cv_attachment: :blob)
        .joins('INNER JOIN cities_jobs ON cities_jobs.job_id = apply_jobs.job_id')
        .joins('INNER JOIN industries_jobs ON industries_jobs.job_id = apply_jobs.job_id')
               .where('email = ? AND cities_jobs.city_id = ?
                       AND industries_jobs.industry_id = ?
                       AND apply_jobs.created_at BETWEEN ? AND ?',
                       applied_params[:email],
                       applied_params[:city],
                       applied_params[:industry],
                       d_start,
                       d_end)
def applied_params
  params.permit(:email, :city, :industry, :date_start, :date_end)
end

当对应的params 是blank 时,如何忽略where 中的子句。如果使用if else 或case when 代码会很长

例如:如果applied_params[:email] 不存在,email = ? 将不会被提及。

【问题讨论】:

    标签: ruby-on-rails performance activerecord rails-activerecord


    【解决方案1】:

    您可以根据提供的输入有条件地链接where 子句:

    query = ApplyJob.includes(:job, cv_attachment: :blob)
                    .joins('INNER JOIN cities_jobs ON cities_jobs.job_id = apply_jobs.job_id')
                    .joins('INNER JOIN industries_jobs ON industries_jobs.job_id = apply_jobs.job_id')
    
    query = query.where(email: applied_params[:email]) if applied_params[:email].present?
    query = query.where(cities_jobs: { city_id: applied_params[:city] }) if applied_params[:city].present?
    

    等等。

    链接where 多次不会立即触发 sql 查询,而是构建单个查询。

    另一种方法是启动如下映射:

    mapping = { 
      ?: { email: applied_params[:email] }, 
      cities_jobs: { city_id: applied_params[:city] },
      industries_jobs: { industry_id: applied_params[:industry] },
      apply_jobs: { created_at: (d_start..d_end if d_start && d_end) }
    }.filter { |_, value| value.compact.presence } 
    

    然后将其传递给where方法:

    query.where(mapping)
    

    【讨论】:

    • 如果用那种方式,就得用很多条件语句
    • 是的,但是没有太多可以省略的。也许你可以声明一个像{ email: { email: applied_params[:email] }, cities_jobs: { city_id: applied_params[:city] }} 这样的映射,通过最深值的存在对其进行过滤,然后传递给where,但映射本身也会很厚
    • 这是对question 的补充。你能帮我看看吗?
    猜你喜欢
    • 1970-01-01
    • 2010-12-30
    • 2021-06-22
    • 2012-07-26
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多