因为想给照片(image 模型)加入 EXIF,所以给 Image 加了叫 exif 的 hstore 项,然后不想费事写每一个单项的名称,所以想到了method_missing
……
写了一段:
def method_missing(m,*a)
if m.to_s =~ /=$/
self.exif[$`] = a[0]
else
raise NoMethodError, "#{m}这个方法你真的定义了嘛>~<人家木有找到耶……"
end
end
后果可想而知……AR 自带的attribute_methods
被覆盖了……
正在翻 AR 源码……不知有没有大神解决过类似问题…………
然后 Rei 大大提供了一种思路
def method_missing(m,*a)
if has_attributes? m
super
else
# code here
end
end
虽然最后被报错嵌套过深……
#1 楼 @Rei 但是在 Rails Console 里测试结果是这段是先于 AR 进行的……所以 attribute_methods 比如@image.title这些都丢失了呢……
大概这样
def method_missing(m,*a)
if has_attributes? m
super
else
# code here
end
end
method_missing 很难 debug,建议避免。
话说你用 hstore 不用这个 gem 的么? https://github.com/diogob/activerecord-postgres-hstore 除了[]
,还有很多查询都很方便。
If you are using Rails 4 you don't need this gem as ActiveRecord 4 provides HStore type support out of the box.
exif 是个有限集合,可以不用 method_missing.
把需要的属性定义到一个 array 里面,然后 define_method 就好了,这样有一个好处就是想要显示什么属性什么是可控的。
def self.exif_include(*attrs)
attrs.each do |attr|
self.class_eval %Q{
def #{attr}
exif[:#{attr}]
end
def #{attr}=(something)
exif[:#{attr}] = something
end
}
end
end
exif_include :camera, :aperture
这样实现了……
#16 楼 @cassiuschen 看了这段才知道你想要什么 试试这个: http://api.rubyonrails.org/classes/ActiveRecord/Store.html