Rails技巧: Handling nil in method calls

缘起:
Martinruby-lang.org.cn发起了一个栏目"每日一题",非常有趣,第一期的两道题目中的第二题描述如下:

我们在项目中经常遇到去关联对象的属性,而关联对象又经常为空,则需要做nil?的判断。譬如

class Coment<AR
  belongs_to :user
end

class User<AR
  has_many :comments
end
 我们在使用的时候一般如下:
unless @comment.user.nil?
   puts @comment.user.login
end

 想个方法简化他,去掉这冗余的nil?判断

 

恰好我前日看到一篇Blog专门讨论这个问题,并给出一个非常不错的办法,避免每次关联对象调用时,先要判断对象是否为nil这么一个步骤,非常的DRY.

 

具体做法是利用ruby的openclass,并非常巧妙的利用了method-messing机制.自定义一个nil_or方法并插入到ruby的Class类中,让Class的对象有了自我检测的能力,如果方法调用接收者的那个对象是nil,则创建一个新的Class实例nil返回,反之则返回对象的方法调用结果.

 

module ObjectExtension
  def nil_or
    return self unless self.nil?
    Class.new do
      def method_missing(sym, *args); nil; end
    end.new
  end  
end

class Object
  include ObjectExtension
end

还用题目中的模型为例,用法是这样:

@comment.user.nil_or.login
即如果Comment的实例@comment的父对象user实例不存在,这个方法调用将直接返回nil,如果存在,则返回父对象user的login方法调用的结果.

 

 

 

你可能感兴趣的:(Blog,Ruby,Rails)