acts_as_countable
2007年3月28日星期三
我想找到一个类似acts_as_commentable和acts_as_rateable的plugins,给任何一个object统计阅读次数,结果没有找到。于是开始动手写一个acts_as_countable,由于编写时间较短,该插件虽然实现了counter的功能,但效率低下,而且在page_cache时无法使用,以下是公开的源代码,有需要的朋友可以加以改进。
一、Create Table
CREATE TABLE `counts` (
`id` int(11) NOT NULL auto_increment,
`count` int(11) default ‘1′,
`created_at` datetime NOT NULL,
`countable_id` int(11) NOT NULL default ‘0′,
`countable_type` varchar(15) NOT NULL default ‘’,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
二、Create plugin
ruby script/generate plugin acts_as_countable
三、Open /vendor/plugins/act_as_countable/lib/act_as_countable.rb and put this code inside:
# ActsAsCountable
module Jesse
module Acts #:nodoc:
module Countable #:nodoc:def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_countable
has_many :counts, :as => :countable, :dependent => :destroy, rder => ‘created_at DESC’
include Jesse::Acts::Countable::InstanceMethods
extend Jesse::Acts::Countable::SingletonMethods
end
end
module SingletonMethods
def find_counts_for(obj)
countable = ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
Count.find(:first,
:conditions => [”countable_id = ? and countable_type = ?”, obj.id, countable])
end
end
module InstanceMethods
def counter
Count.find(:first,
:conditions => [”countable_id = ? and countable_type = ?”, id, self.type.name])
end
# Helper method that defaults the submitted time.
def add_count(count)
counter = Count.find(:first, :conditions => [”countable_id = ? and countable_type = ?”, count.countable_id, self.type.name ])
if counter.nil?
counts << count
else
counter.update_attribute(:count, counter.count + 1)
end
end
endend
end
end
四、Create /vendor/plugins/act_as_countable/lib/count.rb and put this code inside:
class Count < ActiveRecord::Base
belongs_to :countable, :polymorphic => truedef self.find_counts_for_countable(countable_str, countable_id)
find(:first,
:conditions => [”countable_type = ? and countable_id = ?”, countable_str, countable_id]
)
enddef self.find_countable(countable_str, countable_id)
countable_str.constantize.find(countable_id)
end
end
五、put this code inside our /vendor/plugins/act_as_countable/init.rb
require ‘acts_as_countable’
ActiveRecord::Base.send(:include, Jesse::Acts::Countable)
六、How to Use
1. put acts_as_countable inside model, like acts_as_commentable
2. in view action:
count = Count.new
count.countable_id = @obj.id
@obj.add_count(count)
Resources:
标签: Technologies
发表评论
订阅 博文评论 [Atom]
<< 主页