单表继承
官方文档:http://api.rubyonrails.org/classes/ActiveRecord/Base.html
单表继承,在数据库中只有一张表,但映射了了两个以上的model。
比如:文章和相册的分类
文章有文章的分类,相册也有相册的分类。你可以建立两张表,也可以只建立一张表以一个字段值进行区分。
ActioveRecord使用的是建立一张表,用一个type字段,进行区分不同的model。type字段的值为model的类名
如下:
class Category < ActiveRecord::Base
has_many :articles
has_many :photos
end
class PhotoCategory < Category
end
class ArticleCategory < Category
end
create_table :categories,:force => true do |t|
t.column :category_name,:string
t.column :type,:string
end
关于集合的size,count,length
ac = ArticleCategory.find 1
ac.articles.length #=> select * from articles where category_id=1
ac.articles.size#=>select count(*) as count_all from articles where category_id=1
ac.articles.count#=>select count(*) as count_all from articles where category_id=1
可见,如果只是取得记录的数量,就应该避免使用length方法,这个方法会把数据全部取出然后再计算数量。至于size和count效果相同,具体为什么恐怕要从源码上找答案了。
RecordNotFound
find的方法当利用id查询的时候,如果没有记录怎会抛出RecordNotFound的错误。
下面代码,应该很常见了
a = Article.find 1
if a
#something
end
当id为1的文章记录不存在时,真的就返回nil么?
我们当然希望是,只不过需要稍加修改。
思路是,自己添加一个find方法,对父类的find方法进行覆盖。在自己的find方法中调用父类的find方法,当抛出RecordNotFound异常时,返回一个nil值。
代码如下
module HelperModel
def find(*args)
begin
return super
rescue ActiveRecord::RecordNotFound=>ex
return nil
end
end
end
然后在你需要的model中引入,如:
class Photo < ActiveRecord::Base
extend(HelperModel)
end
这样,对find方法的调用则永远不会抛出RecordNotFound异常了,而以nil为代替返回。