Last active
December 16, 2015 22:29
-
-
Save aaronjensen/5507445 to your computer and use it in GitHub Desktop.
model sync stuff for https://github.com/chrismccord/sync/issues/23#issuecomment-17376639
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module EnableModelSync | |
| extend ActiveSupport::Concern | |
| included do | |
| around_filter :enable_sync | |
| end | |
| def enable_sync | |
| ModelSync.enable(self) do | |
| yield | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module ModelSync | |
| extend ActiveSupport::Concern | |
| include Sync::Actions | |
| def self.enabled? | |
| Thread.current["model_sync_enabled"] | |
| end | |
| def self.context | |
| Thread.current["model_sync_context"] | |
| end | |
| def self.enable!(context = nil) | |
| Thread.current["model_sync_enabled"] = true | |
| Thread.current["model_sync_context"] = context | |
| end | |
| def self.disable! | |
| Thread.current["model_sync_enabled"] = false | |
| Thread.current["model_sync_context"] = nil | |
| end | |
| def self.enable(context = nil) | |
| enable!(context) | |
| yield | |
| ensure | |
| disable! | |
| end | |
| module ClassMethods | |
| attr_accessor :sync_parent | |
| def sync(*actions, parent: nil) | |
| include Model | |
| @sync_parent = parent | |
| actions = [:create, :update, :destroy] if actions.include? :all | |
| actions.flatten! | |
| after_create :sync_after_create if actions.include? :create | |
| after_update :sync_after_update if actions.include? :update | |
| after_destroy :sync_after_destroy if actions.include? :destroy | |
| end | |
| end | |
| module Model | |
| def sync_parent | |
| return nil unless self.class.sync_parent | |
| send self.class.sync_parent | |
| end | |
| def sync_context | |
| ModelSync.context || self | |
| end | |
| def sync_after_create | |
| return unless ModelSync.enabled? | |
| sync_context.sync_new self, scope: sync_parent if ModelSync.enabled? | |
| end | |
| def sync_after_update | |
| return unless ModelSync.enabled? | |
| if sync_parent | |
| sync_context.sync_update [self, sync_parent.reload] | |
| else | |
| sync_context.sync_update self | |
| end | |
| end | |
| def sync_after_destroy | |
| return unless ModelSync.enabled? | |
| sync_context.sync_destroy self | |
| sync_context.sync_update sync_parent.reload if sync_parent | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'spec_helper' | |
| describe ModelSync do | |
| it 'can is disabled by default' do | |
| ModelSync.should_not be_enabled | |
| end | |
| it 'can be enabled and disabled' do | |
| ModelSync.enable! | |
| ModelSync.should be_enabled | |
| ModelSync.disable! | |
| ModelSync.should_not be_enabled | |
| end | |
| it 'can be given a block to have things enabled in' do | |
| ModelSync.enable do | |
| ModelSync.should be_enabled | |
| end | |
| ModelSync.should_not be_enabled | |
| end | |
| class FakeModel < ActiveRecord::Base | |
| include ModelSync | |
| self.table_name = 'tags' | |
| sync :all | |
| end | |
| let(:model) { FakeModel.new name: "Foo" } | |
| it 'can be mixed in to a model to allow sync' do | |
| model.stub(:sync_new) | |
| model.stub(:sync_update) | |
| model.stub(:sync_destroy) | |
| ModelSync.enable do | |
| model.save! | |
| model.should have_received(:sync_new).with(model, scope: nil) | |
| model.save! | |
| model.should have_received(:sync_update).with(model) | |
| model.destroy! | |
| model.should have_received(:sync_destroy).with(model) | |
| end | |
| end | |
| it 'does not have a sync parent if it is not specified' do | |
| model.sync_parent.should_not be | |
| end | |
| it 'does not sync if sync is not enabled' do | |
| model = FakeModel.new name: "Foo" | |
| model.stub(:sync_new) | |
| model.save! | |
| model.should_not have_received(:sync_new).with(model) | |
| end | |
| class FakeModelWithParent < ActiveRecord::Base | |
| include ModelSync | |
| self.table_name = 'tags' | |
| sync :all, parent: :my_parent | |
| end | |
| it 'can have a parent specified when mixed into the model' do | |
| model = FakeModelWithParent.new | |
| parent = double("Parent") | |
| model.stub(:sync_new) | |
| model.stub(:sync_update) | |
| model.stub(:sync_destroy) | |
| model.stub(:my_parent) { parent } | |
| parent.stub(:reload) { parent } | |
| model.sync_parent.should == parent | |
| ModelSync.enable do | |
| model.save! | |
| model.should have_received(:sync_new).with(model, scope: parent) | |
| model.save! | |
| model.should have_received(:sync_update).with([model, parent]) | |
| parent.should have_received(:reload) | |
| model.destroy! | |
| model.should have_received(:sync_destroy).with(model) | |
| model.should have_received(:sync_update).with(parent) | |
| parent.should have_received(:reload).twice | |
| end | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment