115 lines
2.3 KiB
Ruby
115 lines
2.3 KiB
Ruby
class PostHistory < ActiveRecord::Base
|
|
class Error < Exception ; end
|
|
|
|
class Revision
|
|
attr_accessor :prev, :hash, :diff, :tag_array
|
|
|
|
def initialize(hash)
|
|
@hash = hash
|
|
@diff = {}
|
|
@tag_array = Tag.scan_tags(@hash["tag_string"])
|
|
end
|
|
|
|
def calculate_diff
|
|
if prev.nil?
|
|
diff[:add] = tag_array
|
|
diff[:del] = []
|
|
diff[:rating] = rating
|
|
diff[:source] = source
|
|
diff[:parent_id] = parent_id
|
|
else
|
|
diff[:del] = prev.tag_array - tag_array
|
|
diff[:add] = tag_array - prev.tag_array
|
|
|
|
if prev.rating != rating
|
|
diff[:rating] = rating
|
|
end
|
|
|
|
if prev.source != source
|
|
diff[:source] = source
|
|
end
|
|
|
|
if prev.parent_id != parent_id
|
|
diff[:parent_id]= parent_id
|
|
end
|
|
end
|
|
end
|
|
|
|
def rating
|
|
hash["rating"]
|
|
end
|
|
|
|
def source
|
|
hash["source"]
|
|
end
|
|
|
|
def parent_id
|
|
hash["parent_id"]
|
|
end
|
|
|
|
def updated_at
|
|
hash["updated_at"]
|
|
end
|
|
|
|
def user_id
|
|
hash["user_id"]
|
|
end
|
|
|
|
def presenter
|
|
@presenter ||= PostHistoryRevisionPresenter.new(self)
|
|
end
|
|
end
|
|
|
|
before_validation :initialize_revisions, :on => :create
|
|
belongs_to :post
|
|
|
|
def self.build_revision_for_post(post)
|
|
hash = {
|
|
:source => post.source,
|
|
:rating => post.rating,
|
|
:tag_string => post.tag_string,
|
|
:parent_id => post.parent_id,
|
|
:user_id => CurrentUser.id,
|
|
:ip_addr => CurrentUser.ip_addr,
|
|
:updated_at => revision_time
|
|
}
|
|
end
|
|
|
|
def self.revision_time
|
|
Time.now
|
|
end
|
|
|
|
def initialize_revisions
|
|
write_attribute(:revisions, "[]")
|
|
end
|
|
|
|
def revisions
|
|
if read_attribute(:revisions).blank?
|
|
[]
|
|
else
|
|
JSON.parse(read_attribute(:revisions))
|
|
end
|
|
end
|
|
|
|
def <<(post)
|
|
revision = self.class.build_revision_for_post(post)
|
|
write_attribute(:revisions, (revisions << revision).to_json)
|
|
save
|
|
end
|
|
|
|
def each_revision(&block)
|
|
array = revisions.map {|x| Revision.new(x)}
|
|
link_revisions(array)
|
|
array.each {|x| x.calculate_diff}
|
|
array.each(&block)
|
|
end
|
|
|
|
private
|
|
def link_revisions(array)
|
|
1.upto(array.size - 1) do |i|
|
|
array[i].prev = array[i - 1]
|
|
end
|
|
end
|
|
|
|
end
|