ActiveRecord 的一些细节
对象属性
ActiveRecord 对象在数据库中的属性并不是以实体变量的方式保存的,如果要为一个属性设置默认值的话,
class Item < ActiveRecord::Base
def category
@category || 'n/a'
end
end
这样的实现是不可行的。读取和修改这些属性时应该使用 read_attribute 和 write_attribute:
class Item < ActiveRecord::Base
def category
read_attribute(:category) || 'n/a'
end
end
Hash 和相等性
ActiveRecord 的 hash 值是根据主键的值计算出来的,这就意味着未保存对象的 hash 值是不可靠的。同样两个 model 对象的相等比较(即==操作符)也是基于主键的,所以两个 model 对象即使它们的其他属性不一样,仍有可能被当作相等。
查找
find_by_attribute 方法后面加个 ! 号,即使用 find_by_attribute!,就能在找不到对象的时候触发一个 RecordNotFound 异常,而不是返回 nil。
find_or_initialize_by 和 find_or_create_by 也是两个好用的方法,它们在找不到对象时分别使用 new 和 create 新建一个,并用查找的属性初始化新建的对象。
手写 SQL
不得不手写 SQL 同时又要防止注入攻击的一个比较简洁的写法是
Order.where("name = :name and pay_type = :pay_type", params[:order])
回调函数
出于性能考虑,after_find 和 after_initialize 只能通过函数声明的方式定义,即不能用类似 before_validation :normalize_fields
这样的形式。
参考
本作品采用知识共享署名-非商业性使用 3.0 版本许可协议进行许可,欢迎转载,演绎,但是必须保留本文的署名 zellux(包含链接),且不得用于商业目的。