简体   繁体   English

在Rails中构建动态ActiveRecord查询

[英]Build dynamic ActiveRecord query in Rails

I would like to know how to successfully set out a dynamic Active Record query based on whether the params are present/exist. 我想知道如何根据参数是否存在/存在成功地设置动态Active Record查询。

I have this query 我有这个查询

Animal.joins(:user).where(animal_type: params[:animal_type], rehomed: params[:rehomed], users: {town: params[:animal_town]})

I have tried something along these lines, but my syntax is all wrong, I believe: 我已经尝试了以下方法,但是我的语法是错误的,我相信:

conditions = []
conditions << [ animal_type: params[:animal_type], ] if params[:animal_type].present?
conditions << [ rehomed: params[:rehomed], ] if params[:rehomed].present?
conditions << [ users: {town: params[:animal_town]} ] if params[:animal_town].present?
@animals = Animal.joins(:user).where(conditions)

I don't want to put it all in a nested hash, do I? 我不想将其全部放入嵌套的哈希中,对吗?

You have to do: 你必须做:

conditions = {}
conditions.merge!(animal_type: params[:animal_type]) if params[:animal_type].present?
conditions.merge!(rehomed: params[:rehomed]) if params[:rehomed].present?
conditions.merge!(users: {town: params[:animal_town]}) if params[:animal_town].present?

@animals = Animal.joins(:user).where(conditions)

I would do somethink like this: 我会这样想:

scope = Animal.joins(:user)
scope = scope.where(animal_type: params[:animal_type])     if params[:animal_type].present?
scope = scope.where(rehomed: params[:rehomed])             if params[:rehomed].present?
scope = scope.where(users: { town: params[:animal_town] }) if params[:animal_town].present?

@animals = scope

Further improvements: Move building of the scope into a method in the Animal model: 进一步的改进:将范围的构建移到Animal模型的方法中:

# in controller
@animals = Animal.find_by_query(params.slice(:animal_type, :rehomed, :animal_town))

# in Animal model
def self.find_by_query(query = {})
  query.reject { |_, v| v.blank? }

  scope = joins(:user)
  scope = scope.where(animal_type: query[:animal_type])     if query[:animal_type]
  scope = scope.where(rehomed: query[:rehomed])             if query[:rehomed]
  scope = scope.where(users: { town: query[:animal_town] }) if query[:animal_town]
  scope
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM