ActiveRecord构建动态查询条件

时间:2013-07-08 16:26:44

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

我有一段似乎有用的代码。我认为可能有更好的方法来实现理想的工作。问题是使用未知的参数列表构建ActiveRecord查询。

以下是代码:

query_string = String.new
query_values = []
unless params[:organization][:name].blank?
  query_string << 'name = ?'
  query_values << params[:organization][:name]
end
unless params[:organization][:national_id].blank? && params[:organization][:vat_id].blank?
  raise RequestParamsException.new('National ID or Vat ID given without country') if params[:organization][:country].nil?
  country_id = Country.find_by_name(params[:organization][:country]).pluck(:id)
  unless params[:organization][:national_id].blank?
    query_string << ' OR ' unless query_string.empty?
    query_string << '(national_id = ?'
    query_values << params[:organization][:national_id]
    query_string << ' AND ' << 'country_id = ?)'
    query_values << country_id
  end
  unless params[:organization][:vat_id].blank?
    query_string << ' OR ' unless query_string.empty?
    query_string << '(vat_id = ?'
    query_values << params[:organization][:vat_id]
    query_string << ' AND ' << 'country_id = ?)'
    query_values << country_id
  end
end
known_organizations = query_string.blank? ? [] : Organization.where(query_string, query_values).uniq

当给出增值税或国民身份证时需要国家/地区,因为这些是在模型中确定的范围:

class Organization < ActiveRecord::Base    

#======================VALIDATIONS=========================
  validates :national_id, :uniqueness => { :scope => :country_id }, :allow_blank => true
  validates :vat_id, :uniqueness => { :scope => :country_id }, :allow_blank => true
  validates :country, :presence => true  
end

1 个答案:

答案 0 :(得分:3)

你可以利用Arel。例如,当你写:

posts = Post.where(author_id: 12)

除非您开始在posts上进行迭代或致电posts.all,否则不会执行此查询。所以你可以这样写:

def search_posts
  posts = Post.where(active: true)
  posts = posts.where('body ilike ?', "%#{params[:query]%") unless params[:query].blank? 

  posts
end

这个简单的例子展示了如何实现您正在寻找的行为。