<body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d4684235500622716427\x26blogName\x3dCaiwangqin\x27s+blog\x26publishMode\x3dPUBLISH_MODE_HOSTED\x26navbarType\x3dBLUE\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttp://blog.caiwangqin.com/search\x26blogLocale\x3dzh_CN\x26v\x3d2\x26homepageUrl\x3dhttp://blog.caiwangqin.com/\x26vt\x3d3393395200455623441', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>

Caiwangqin's blog

Focus on Life, Cloud Service, Smart Hardware, Architecture, Technic and beyond…

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, :o 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
end

end
end
end



四、Create /vendor/plugins/act_as_countable/lib/count.rb and put this code inside:


class Count < ActiveRecord::Base
belongs_to :countable, :polymorphic => true


def self.find_counts_for_countable(countable_str, countable_id)
find(:first,
:conditions => [”countable_type = ? and countable_id = ?”, countable_str, countable_id]
)
end

def 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:



标签:

posted by Caiwangqin, 07:42

0 Comments:

发表评论

订阅 博文评论 [Atom]

<< 主页