寂静小站2.0的Model之Post
Published at 5 months ago
Post就是日志,数据库结构如下:
create_table "posts", :force => true do |t| t.text "title" #日志标题 t.text "content" #日志内容 t.text "content_nohtml" #去除html代码后的日志内容 t.text "types" #日志类型,目前有3种:blog,delicious和topic t.text "status" #日志状态,也是3种状态:publish,draft和delete t.datetime "created_at" t.datetime "updated_at" end
可能你会奇怪为何会有content_nohtml这个奇怪的数据列,这个列的作用主要有两个:一个是用于搜索,可以避免搜索到html代码,另一个就是生成文章摘要。 Post有如下方法:
- self.get_posts:获取日志列表
- get_summary:获取日志的摘要
- get_tags:获取日志的Tags列表
- get_similar:获取相关日志列表
- self._search:搜索日志
详细代码如下:
class Post < ActiveRecord::Base
has_one :post_from
has_many :post_dict
def self.get_posts(*options)
options = Hash.options(
options,
{
:types => 'all',
:page => 1
}
)
page = Hash.options(
:per_page => 10,
:select => 'posts.id, posts.title, posts.content_nohtml, posts.types, posts.created_at',
:conditions => 'posts.status = "publish"',
:order => 'posts.updated_at DESC'
)
page[:page] = options[:page]
case options[:types]
when 'search'
keyword = '%' << options[:keyword] << '%'
page[:conditions] = [page[:conditions] << ' AND (title LIKE ? OR content_nohtml LIKE ?)', keyword, keyword]
when 'tag'
page[:conditions] = [page[:conditions] << ' AND post_dicts.dict_id = ?', options[:id]]
page[:include] = :post_dict
when 'all'
else
page[:conditions] = [page[:conditions] << ' AND types = ?', options[:types]]
end
Post.paginate(page)
end
def get_summary
unless self.content_nohtml.blank?
return self.content_nohtml.delete('"').scan(/./)[0, 200].join('')
end
end
def get_tags
tags_id = PostDict.get_dict_id(self.id)
if tags_id.blank?
return nil
else
Dict.find(tags_id)
end
end
def get_similar(*options)
unless self.post_dict.blank?
options = Hash.options(options,{:limit => 5})
dicts = self.post_dict.map{|x| x.dict_id}
sim = Array.new
Post.id_is_not(self.id).each do |sub_post|
if sub_post.status != 'publish' || sub_post.post_dict.blank?
next
end
sum = 0
sub_dicts = sub_post.post_dict.map{|x| x.dict_id}
sum_dicts = dicts & sub_dicts
if sum_dicts.length < 1
next
else
sum_dicts.each do |sum_dict|
main_count = PostDict.post_id_is(self.id).dict_id_is(sum_dict).first.count
sub_count = PostDict.post_id_is(sub_post.id).dict_id_is(sum_dict).first.count
count = 0
count = ([main_count, sub_count].sort![-1] - (main_count - sub_count).abs)
if count > 0
sum = sum + count
end
end
sim[sim.length] = [sum, sub_post]
end
end
if sim.length > 0
sim.sort!{|x,y| x[0] <=> y[0]}
return sim.map{|x| x[1]}[0,options[:limit]]
end
end
end
def self._search(keyword, *options)
keyword = '%' << keyword << '%'
options = Hash.options(options)
find = Hash.options(
:conditions => ['status = "publish" AND (title LIKE ? OR content_nohtml LIKE ?)', keyword, keyword]
)
if options[:limit].blank? == false
find[:limit] = options[:limit]
end
Post.find(:all, find)
end
end
欢迎大家指出不足之处 :)