This repository has been archived by the owner on Sep 7, 2021. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor Mingo with modular design, before/after callbacks
- Loading branch information
Showing
4 changed files
with
147 additions
and
84 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
class Mingo | ||
module Callbacks | ||
def self.included(base) | ||
base.extend ActiveModel::Callbacks | ||
base.send :define_model_callbacks, :create, :save, :update, :destroy | ||
end | ||
|
||
def save(*args) | ||
action = persisted? ? 'update' : 'create' | ||
send(:"_run_#{action}_callbacks") do | ||
_run_save_callbacks { super } | ||
end | ||
end | ||
|
||
def destroy | ||
_run_destroy_callbacks { super } | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
class Mingo | ||
module Changes | ||
def self.included(base) | ||
base.after_save :clear_changes | ||
end | ||
|
||
attr_reader :changes | ||
|
||
def initialize(*args) | ||
@changes = {} | ||
super | ||
end | ||
|
||
def changed? | ||
changes.any? | ||
end | ||
|
||
private | ||
|
||
def _regular_writer(key, value) | ||
track_change(key, value) | ||
super | ||
end | ||
|
||
def track_change(key, value) | ||
old_value = _regular_reader(key) | ||
unless value == old_value | ||
memo = (changes[key.to_sym] ||= [old_value]) | ||
memo[0] == value ? changes.delete(key.to_sym) : (memo[1] = value) | ||
end | ||
end | ||
|
||
def clear_changes | ||
changes.clear | ||
end | ||
|
||
private | ||
|
||
def values_for_update | ||
changes.inject('$set' => {}, '$unset' => {}) do |doc, (key, values)| | ||
value = values[1] | ||
value.nil? ? (doc['$unset'][key] = 1) : (doc['$set'][key] = value) | ||
doc | ||
end | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
require 'active_support/concern' | ||
|
||
class Mingo | ||
module Persistence | ||
extend ActiveSupport::Concern | ||
|
||
module ClassMethods | ||
def create(obj = nil) | ||
new(obj).tap do |object| | ||
yield object if block_given? | ||
object.save | ||
end | ||
end | ||
end | ||
|
||
module InstanceMethods | ||
def initialize(*args) | ||
@destroyed = false | ||
super | ||
end | ||
|
||
def persisted? | ||
!!id | ||
end | ||
|
||
def save(options = {}) | ||
if persisted? | ||
update(values_for_update, options) | ||
else | ||
self['_id'] = self.class.collection.insert(self.to_hash, options) | ||
end | ||
end | ||
|
||
def update(doc, options = {}) | ||
self.class.collection.update({'_id' => self.id}, doc, options) | ||
end | ||
|
||
def reload | ||
doc = self.class.first(id, :convert => nil) | ||
replace doc | ||
end | ||
|
||
def destroy | ||
self.class.collection.remove('_id' => self.id) | ||
@destroyed = true | ||
self.freeze | ||
end | ||
|
||
def destroyed? | ||
@destroyed | ||
end | ||
|
||
private | ||
|
||
def values_for_update | ||
self.to_hash | ||
end | ||
end | ||
end | ||
end |