2012-12-10 38 views
0

我有一个代码结构是这样的:简化if语句和记录检索

if params[:one] && params[:two] 
    object = Something.where(:one => params[:one], :two => params[:two]) 
elsif params[:one] 
    object = Something.where(:one => params[:one]) 
elsif params[:two] 
    object = Something.where(:two => params[:two]) 
else 
    object = Something.all 
end 

基本上,在过滤器进行查询的网址两个可选参数。这可以更清洁吗?

+0

这应该在http://codereview.stackexchange.com上提问。 –

回答

2

我会写:

objects = Something.where(params.slice(:one, :two)) 

注:

  1. 通常一个空的参数是也被认为是不存在的。在这种情况下:Something.where(params.slice(:one, :two).select { |k, v| v.present? })

  2. 奇怪,因为它可能看起来,在你的代码段中,你应该写object = if ...,它更像一个语言,其中条件是表达式而不是语句。

  3. 不要求all作为无操作,你没有ActiveRecord::Relation(酷)了,但Array(不那么酷)。 where({})非常好。

  4. 命名非常重要!如果你看到object你认为“单个元素”(这不是真的),如果你看到objects你认为“收集”。

  5. 如果帕拉姆钥匙不匹配DB列:很多方法去做,例如:

    pairs = {:x => :db_x, :y => db_y}.map { |k, v| [v, params[k]] if params[k] }] 
    Something.where(Hash[pairs.compact]) 
    

或被只有两个属性:

attrs = {:db_one => params[:one], :db_two => params[:two]} 
Something.where(attrs.select { |k, v| v }) 
+0

如果参数没有任何这些键,这个工作是否会起作用?也就是说,将一个空的散列传递给'.where' ...... – PinnyM

+0

是的,'哪里({})'没有过滤。 – tokland

+0

@tokland感谢您的回复。如果param键不直接对应数据库列,那么语法是什么? – FelixMM

0

你可能会考虑做类似的事情(链接标准):

object = Something.all 
object = object.where(:one => params[:one]) if params[:one] 
object = object.where(:two => params[:two]) if params[:two]