Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use ActiveSupport Concern #289

Merged
merged 3 commits into from
Oct 29, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 50 additions & 40 deletions lib/paper_trail/version.rb
Original file line number Diff line number Diff line change
@@ -1,55 +1,62 @@
module PaperTrail
class Version < ::ActiveRecord::Base
belongs_to :item, :polymorphic => true
validates_presence_of :event
attr_accessible :item_type, :item_id, :event, :whodunnit, :object, :object_changes if PaperTrail.active_record_protected_attributes?
require 'active_support/concern'

after_create :enforce_version_limit!
module PaperTrail
module VersionConcern
extend ActiveSupport::Concern
included do
belongs_to :item, :polymorphic => true
validates_presence_of :event
attr_accessible :item_type, :item_id, :event, :whodunnit, :object, :object_changes if PaperTrail.active_record_protected_attributes?

def self.with_item_keys(item_type, item_id)
where :item_type => item_type, :item_id => item_id
after_create :enforce_version_limit!
end

def self.creates
where :event => 'create'
end
module ClassMethods
def with_item_keys(item_type, item_id)
where :item_type => item_type, :item_id => item_id
end

def self.updates
where :event => 'update'
end
def creates
where :event => 'create'
end

def self.destroys
where :event => 'destroy'
end
def updates
where :event => 'update'
end

def self.not_creates
where 'event <> ?', 'create'
end
def destroys
where :event => 'destroy'
end

# These methods accept a timestamp or a version and returns other versions that come before or after
def self.subsequent(obj)
obj = obj.send(PaperTrail.timestamp_field) if obj.is_a?(self)
where("#{PaperTrail.timestamp_field} > ?", obj).order("#{PaperTrail.timestamp_field} ASC")
end
def not_creates
where 'event <> ?', 'create'
end

def self.preceding(obj)
obj = obj.send(PaperTrail.timestamp_field) if obj.is_a?(self)
where("#{PaperTrail.timestamp_field} < ?", obj).order("#{PaperTrail.timestamp_field} DESC")
end
# These methods accept a timestamp or a version and returns other versions that come before or after
def subsequent(obj)
obj = obj.send(PaperTrail.timestamp_field) if obj.is_a?(self)
where("#{PaperTrail.timestamp_field} > ?", obj).order("#{PaperTrail.timestamp_field} ASC")
end

def self.between(start_time, end_time)
where("#{PaperTrail.timestamp_field} > ? AND #{PaperTrail.timestamp_field} < ?", start_time, end_time).
order("#{PaperTrail.timestamp_field} ASC")
end
def preceding(obj)
obj = obj.send(PaperTrail.timestamp_field) if obj.is_a?(self)
where("#{PaperTrail.timestamp_field} < ?", obj).order("#{PaperTrail.timestamp_field} DESC")
end

# Returns whether the `object` column is using the `json` type supported by PostgreSQL
def self.object_col_is_json?
@object_col_is_json ||= columns_hash['object'].type == :json
end
def between(start_time, end_time)
where("#{PaperTrail.timestamp_field} > ? AND #{PaperTrail.timestamp_field} < ?", start_time, end_time).
order("#{PaperTrail.timestamp_field} ASC")
end

# Returns whether the `object` column is using the `json` type supported by PostgreSQL
def object_col_is_json?
@object_col_is_json ||= columns_hash['object'].type == :json
end

# Returns whether the `object_changes` column is using the `json` type supported by PostgreSQL
def self.object_changes_col_is_json?
@object_changes_col_is_json ||= columns_hash['object_changes'].type == :json
# Returns whether the `object_changes` column is using the `json` type supported by PostgreSQL
def object_changes_col_is_json?
@object_changes_col_is_json ||= columns_hash['object_changes'].type == :json
end
end

# Restore the item from this version.
Expand Down Expand Up @@ -205,6 +212,9 @@ def enforce_version_limit!
excess_previous_versions = previous_versions - previous_versions.last(PaperTrail.config.version_limit)
excess_previous_versions.map(&:destroy)
end
end

class Version < ::ActiveRecord::Base
include VersionConcern
end
end
46 changes: 46 additions & 0 deletions spec/models/version_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
require 'spec_helper'

module Foo
class Base < ActiveRecord::Base
self.abstract_class = true
end

class Document < Base
has_paper_trail :class_name => 'Foo::Version'
end

class Version < Base
include PaperTrail::VersionConcern
end
end
Foo::Base.establish_connection(:adapter => 'sqlite3', :database => File.expand_path('../../../test/dummy/db/test-foo.sqlite3', __FILE__))

module Bar
class Base < ActiveRecord::Base
self.abstract_class = true
end

class Document < Base
has_paper_trail :class_name => 'Bar::Version'
end

class Version < Base
include PaperTrail::VersionConcern
end
end
Bar::Base.establish_connection(:adapter => 'sqlite3', :database => File.expand_path('../../../test/dummy/db/test-bar.sqlite3', __FILE__))

describe PaperTrail::VersionConcern do
it 'allows included class to have different connections' do
Foo::Version.connection.should_not eq Bar::Version.connection
end

it 'allows custom version class to share connection with superclass' do
Foo::Version.connection.should eq Foo::Document.connection
Bar::Version.connection.should eq Bar::Document.connection
end

it 'can be used with class_name option' do
Foo::Document.version_class_name.should eq 'Foo::Version'
Bar::Document.version_class_name.should eq 'Bar::Version'
end
end

describe PaperTrail::Version do
describe "Attributes" do
it { should have_db_column(:item_type).of_type(:string) }
Expand Down