Created
May 22, 2012 14:22
-
-
Save sebthemonster/2769377 to your computer and use it in GitHub Desktop.
A Module to decoupling persistence from business model
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 Persistence | |
module Mapper | |
extend ActiveSupport::Concern | |
included do | |
extend ActiveModel::Naming | |
include ActiveModel::Conversion | |
end | |
module ClassMethods | |
def find(id) | |
new.tap do |model| | |
model.persistence = persistence_class.find(id) | |
end | |
end | |
def method_missing(meth, *args, &blk) | |
persistence_class.send meth, *args, &blk | |
end | |
def persistence_class | |
@persistence_class ||= ("Persistence::#{name}".constantize rescue nil) | |
end | |
private | |
def persistence_class=(klass) | |
@persistence_class = (klass.is_a?(String) ? klass.constantize : klass) | |
@persistence_class | |
end | |
end | |
attr_accessor :persistence | |
def initialize(obj = nil) | |
raise "a persistence class is needed. Create one Persistence::#{self.to_model} or specify it with persistence_class= method." if self.class.persistence_class.nil? | |
if obj.is_a? self.class.persistence_class | |
@persistence = obj | |
else | |
@persistence = self.class.persistence_class.new obj | |
end | |
super | |
end | |
def create attrs | |
attrs.each do |k,v| | |
self.public_send "#{k}=", v | |
end | |
self.save! | |
end | |
def method_missing(meth, *args) | |
unless @persistence | |
@persistence = self.class.persistence_class.new | |
end | |
@persistence.send(meth, *args) | |
end | |
end | |
#module Base | |
# include ActiveSupport::Concern | |
# def to_model(klass) | |
# klass | |
# 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" | |
require_relative '../../lib/persistence_mapper' | |
describe Persistence::Mapper do | |
class Persistence::Model; end | |
subject do | |
class Model | |
include Persistence::Mapper | |
end | |
Model | |
end | |
let(:persistence_class) { stub(:persistence).as_null_object } | |
context "ClassMethods" do | |
context '#persistence_class' do | |
it "should set automatically persistence to a Persistence class by default" do | |
subject.persistence_class.should == Persistence::Model | |
end | |
it "should set automatically persistence to nil if Persistence Class doesn't exist" do | |
class MyClass; include Persistence::Mapper; end | |
MyClass.persistence_class.should be_nil | |
end | |
end | |
context "#method_missing" do | |
it "should delegate chain methods to persistence" do | |
subject.send( :persistence_class=, persistence_class) | |
persistence_class.should_receive(:unknown_method) | |
subject.unknown_method | |
end | |
end | |
end | |
context 'InstanceMethods' do | |
let(:object) { subject.new } | |
let(:persistence) { stub(:persistence).as_null_object } | |
before { | |
subject.stub(:persistence_class).and_return(Persistence::Model) | |
} | |
it "should raise an error if has no persistence_class" do | |
subject.stub(:persistence_class).and_return(nil) | |
expect { subject.new }.should raise_error | |
end | |
it "should initialize with a new persistence object" do | |
Persistence::Model.should_receive(:new) | |
subject.new | |
end | |
it "should delegate methods to persistence object" do | |
Persistence::Model.stub(:new).and_return(persistence) | |
persistence.should_receive(:unknown_method) | |
object.unknown_method | |
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
#models/article.rb : | |
require 'persistence_mapper' | |
require_relative '../persistence/lotissement' | |
class Article | |
include Persistence::Mapper | |
end | |
#persistence/article.rb : | |
module Persistence | |
class Article < ActiveRecord::Base | |
belongs_to :author | |
validates_presence_of :title | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment