Skip to content

Commit

Permalink
Merge pull request #3 from ajvargo/interface_updates
Browse files Browse the repository at this point in the history
Add before_set_revision callback to options
  • Loading branch information
jzaleski committed Aug 12, 2014
2 parents 433a6a1 + 959f140 commit ce15b5c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
acts_as_revisionable (1.2.3.sermo)
acts_as_revisionable (1.3.0.sermo)
activerecord (~> 3.2)

GEM
Expand Down
24 changes: 14 additions & 10 deletions lib/acts_as_revisionable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module ActsMethods
# acts_as_revisionable :meta => {
# :updated_by => :last_updated_by,
# :label => lambda{|record| "Updated by #{record.updated_by} at #{record.updated_at}"},
# :before_store_revision => :callback_executed_on_read_only_object_to_be_versioned
# :version => 1
# }
#
Expand Down Expand Up @@ -202,7 +203,7 @@ def last_revision
end

# Call this method to implement revisioning. The object changes should happen inside the block.
def store_revision
def store_revision(*args)
if new_record? || @revisions_disabled
return yield
else
Expand All @@ -213,7 +214,11 @@ def store_revision
begin
read_only = self.class.first(:conditions => {self.class.primary_key => self.id}, :readonly => true)
if read_only
revision = read_only.create_revision!(self)
callback = self.class.acts_as_revisionable_options[:before_store_revision]
if callback
read_only.send(self.class.acts_as_revisionable_options[:before_store_revision], *args)
end
revision = read_only.create_revision!
truncate_revisions!
end
rescue => e
Expand Down Expand Up @@ -244,17 +249,17 @@ def store_revision
end

# Build a revision record based on this record
def build_revision(base_record = self)
def build_revision
revision_options = self.class.acts_as_revisionable_options
revision = revision_record_class.new(self, revision_options[:encoding])
set_revision_meta_attributes(revision_options[:meta], revision, base_record)
set_revision_meta_attributes(revision_options[:meta], revision)

revision
end

# Create a revision record based on this record and save it to the database.
def create_revision!(base_record = self)
revision = build_revision(base_record)
def create_revision!
revision = build_revision
revision.save!
revision
end
Expand Down Expand Up @@ -298,18 +303,17 @@ def update_with_revision
end
end

def set_revision_meta_attributes(meta_options, revision, base_record = self)
def set_revision_meta_attributes(meta_options, revision)
if meta_options.is_a?(Hash)
meta_options.each do |attribute, value|
set_revision_meta_attribute(revision, attribute, value)
end
elsif meta_options.is_a?(Array)
meta_options.each do |attribute|
set_revision_meta_attributes(attribute, revision, base_record)
set_revision_meta_attribute(revision, attribute, attribute.to_sym)
end
elsif meta_options
value = base_record.send(meta_options)
set_revision_meta_attribute(revision, meta_options, value)
set_revision_meta_attribute(revision, meta_options, meta_options.to_sym)
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/acts_as_revisionable/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ActsAsRevisionable
VERSION = '1.2.3.sermo'
VERSION = '1.3.0.sermo'
end
76 changes: 46 additions & 30 deletions spec/acts_as_revisionable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,36 @@ class OtherRevisionableTestModel < ActiveRecord::Base
class AnotherRevisionableTestModel < ActiveRecord::Base
connection.create_table(table_name) do |t|
t.string :name
t.string :updated_by
end unless table_exists?
attr_accessor :label
acts_as_revisionable :meta => :label, :class_name => RevisionRecord2

attr_reader :label, :updated_by
acts_as_revisionable :before_store_revision => :set_info,
:class_name => "RevisionRecord2",
:meta => [:label, :updated_by]

private

def set_info(text, who)
@label = text
@updated_by = who
end
end

class YetAnotherRevisionableTestModel < ActiveRecord::Base
connection.create_table(table_name) do |t|
t.string :name
t.string :updated_by
end unless table_exists?
attr_accessor :label, :album
acts_as_revisionable :meta => [:label, :album], :class_name => RevisionRecord3

attr_reader :label
acts_as_revisionable :before_store_revision => :set_label,
:class_name => "RevisionRecord2",
:meta => :label

private

def set_label
@label = 'WOW! It works!'
end
end

module ActsAsRevisionable
Expand Down Expand Up @@ -233,30 +250,6 @@ class RevisionableSubclassModel < RevisionableNamespaceModel
ActsAsRevisionable::RevisionRecord.count.should == 1
end

it "should bring non-database backed accessor values forward into revisions if used as meta data" do
record = AnotherRevisionableTestModel.new(:name => "test")
record.label = "Alternative Tentacles"
record.save!
record.store_revision do
record.name = "new name"
record.save!
end
record.last_revision.label.should == "Alternative Tentacles"
end

it "should bring an array of non-database backed accessor values forward into revisions if used as meta data" do
record = YetAnotherRevisionableTestModel.new(:name => "test")
record.label = "Alternative Tentacles"
record.album = "Fresh Fruit for Rotting Vegetables"
record.save!
record.store_revision do
record.name = "new name"
record.save!
end
record.last_revision.label.should == "Alternative Tentacles"
record.last_revision.album.should == "Fresh Fruit for Rotting Vegetables"
end

it "should always store revisions whenever a record is saved if :on_update is true" do
record = OtherRevisionableTestModel.create!(:name => "test")
record.name = "new name"
Expand Down Expand Up @@ -316,6 +309,29 @@ class RevisionableSubclassModel < RevisionableNamespaceModel
ActsAsRevisionable::RevisionRecord.count.should == 1
end

describe "call back options" do
it "should call the provided function with passed data" do
record = AnotherRevisionableTestModel.create!(:name => "Larry Bo-Barry")

record.store_revision("ding", "dong") do
record.name = "Sally Sally"
record.save!
end
record.last_revision.label.should == "ding"
record.last_revision.updated_by.should == "dong"
end

it "should call the provided function if it doesn't take data" do
record = YetAnotherRevisionableTestModel.create!(:name => "Larry Bo-Barry")

record.store_revision do
record.name = "Sally Sally"
record.save!
end
record.last_revision.label.should == "WOW! It works!"
end
end

describe "metadata" do
context "when creating a revision record" do
it "should set metadata on the revison using a complex attribute to value mapping" do
Expand Down

0 comments on commit ce15b5c

Please sign in to comment.