簡體   English   中英

動態記錄中的動態查找條件

[英]Dynamic find conditions in active record

我在rails中有一個索引動作,可以處理很多參數,例如:

params[:first_name] # can be nil or first_name
params[:age]        # can be nil or age 
params[:country]    # can be nil or country

當找到用戶時,我想和所有不是零的條件。 這給了我8個查找條件的排列。

我怎樣才能保持我的代碼DRY和靈活性,而不是為了構建查找條件而得到一堆if語句。 請記住,如果沒有指定條件,我只想返回User.all

怎么樣的:

conditions = params.only(:first_name, :age, :country)
conditions = conditions.delete_if {|key, value| value.blank?}

if conditions.empty?
  User.all
else
  User.all(:conditions => conditions)
end

我通常會使用這樣的命名范圍:

class User < ActiveRecord::Base
  named_scope :name_like, lambda {|name| {:conditions => ["first_name LIKE ?", "#{name}%"]}}
  named_scope :age, lambda {|age| {:conditions => {:age => age}}}
  named_scope :in_country, lambda {|country| {:conditions => {:country => country}}}
end

class UsersController < ActionController
  def index
    root = User
    root = root.name_like(params[:first_name]) unless params[:first_name].blank?
    root = root.age(params[:age]) unless params[:age].blank?
    root = root.country(params[:country]) unless params[:age].blank?

    @users = root.paginate(params[:page], :order => "first_name")
  end
end

這就是我通常做的事情。

這看起來效果很好:

conditions = params.slice(:first_name, :age, :country)
hash = conditions.empty? ? {} : {:conditions => conditions}
@users = User.all hash 

使用James Healy回答,我修改了在Rails 3.2中使用的代碼(如果有人需要這個)。

conditions = params.slice(:first_name, :age, :country)
conditions = conditions.delete_if {|key, value| value.blank?}

@users = User.where(conditions)

您可以嘗試Ambition或許多其他ActiveRecord擴展。

如果您碰巧在一個古老的項目(Rails 2.x)上並且非常混亂,您可以執行類似以下操作,以便在原始查詢中添加新字段。

原始代碼:

User.find(:all,
   :conditions => ['first_name LIKE ? AND age=? AND country=?',
        "#{name}%", age, country]

zip_code字段上添加新的動態條件:

zip_code  = params[:zip_code]   # Can be blank
zip_query = "AND zip_code = ?" unless zip_code.blank?

User.find(:all,
   :conditions => ['first_name LIKE ? AND age=? AND country=? #{zip_query}',
        "#{name}%", age, country, zip_code].reject(&:blank?)

conditions數組添加reject(&:blank?)將過濾nil值。

注意:如果您從零編碼或重構,其他答案要好得多。

這對我也有用

conditions = params[:search] ? params[:search].keep_if{|key, value| !value.blank?} : {}
User.all(:conditions => conditions)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM