寂静小站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有如下方法:

详细代码如下:

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

  欢迎大家指出不足之处 :)

#Ruby on Rails

@http://zfben.com/blog/寂静小站2.0的Model之Post