Permalink
Browse files

Adding initial inheritance support to designs ... needs a bit more te…

…sting to ensure views a prepared correctly
  • Loading branch information...
1 parent 7f0d1a1 commit 1796e6366a3465c5c19c3d83a5be7e612cf757a6 @samlown samlown committed Jun 8, 2012
Showing with 81 additions and 5 deletions.
  1. +21 −3 lib/couchrest/model/designs.rb
  2. +60 −2 spec/unit/designs_spec.rb
View
24 lib/couchrest/model/designs.rb
@@ -25,13 +25,28 @@ module ClassMethods
# Add views and other design document features
# to the current model.
def design(prefix = nil, &block)
+
+ # Store ourselves a copy of this design spec incase any other model inherits.
+ (@_design_blocks ||= [ ]) << {:args => [prefix], :block => block}
+
mapper = DesignMapper.new(self, prefix)
mapper.instance_eval(&block) if block_given?
# Create an 'all' view if no prefix and one has not been defined already
mapper.view(:all) if prefix.nil? and !mapper.design_doc.has_view?(:all)
end
+ def inherited(model)
+ super
+
+ # Go through our design blocks and re-implement them in the child.
+ unless @_design_blocks.nil?
+ @_design_blocks.each do |row|
+ model.design(*row[:args], &row[:block])
+ end
+ end
+ end
+
# Override the default page pagination value:
#
# class Person < CouchRest::Model::Base
@@ -70,8 +85,8 @@ def initialize(model, prefix = nil)
self.prefix = prefix
self.method = Design.method_name(prefix)
- self.design_doc = (model.respond_to?(method) ?
- model.send(method) : create_model_design_doc_reader)
+ create_model_design_doc_reader
+ self.design_doc = model.send(method) || assign_model_design_doc
end
def disable_auto_update
@@ -108,8 +123,11 @@ def model_type_key
# Create accessor in model and assign a new design doc.
# New design doc is returned ready to use.
def create_model_design_doc_reader
- doc = Design.new(model, prefix)
model.instance_eval "def #{method}; @#{method}; end"
+ end
+
+ def assign_model_design_doc
+ doc = Design.new(model, prefix)
model.instance_variable_set("@#{method}", doc)
model.design_docs << doc
View
62 spec/unit/designs_spec.rb
@@ -2,6 +2,7 @@
class DesignModel < CouchRest::Model::Base
use_database DB
+ property :name
end
describe CouchRest::Model::Designs do
@@ -30,15 +31,72 @@ class DesignModel < CouchRest::Model::Base
@klass.should respond_to(:stats_design_doc)
@klass.should_not respond_to(:all)
end
+
+ it "should have added itself to a design_blocks array" do
+ @klass.design
+ blocks = @klass.instance_variable_get(:@_design_blocks)
+ blocks.length.should eql(1)
+ blocks.first.should eql({:args => [nil], :block => nil})
+ end
+
+ it "should have added itself to a design_blocks array" do
+ @klass.design
+ blocks = @klass.instance_variable_get(:@_design_blocks)
+ blocks.length.should eql(1)
+ blocks.first.should eql({:args => [nil], :block => nil})
+ end
+
+ it "should have added itself to a design_blocks array with prefix" do
+ @klass.design :stats
+ blocks = @klass.instance_variable_get(:@_design_blocks)
+ blocks.length.should eql(1)
+ blocks.first.should eql({:args => [:stats], :block => nil})
+ end
end
describe "with block" do
- it "should pass calls to mapper" do
- @klass.design do
+ before :each do
+ @block = Proc.new do
disable_auto_update
end
+ @klass.design &@block
+ end
+
+ it "should pass calls to mapper" do
@klass.design_doc.auto_update.should be_false
end
+
+ it "should have added itself to a design_blocks array" do
+ blocks = @klass.instance_variable_get(:@_design_blocks)
+ blocks.length.should eql(1)
+ blocks.first.should eql({:args => [nil], :block => @block})
+ end
+
+ it "should handle multiple designs" do
+ @block2 = Proc.new do
+ view :by_name
+ end
+ @klass.design :stats, &@block2
+ blocks = @klass.instance_variable_get(:@_design_blocks)
+ blocks.length.should eql(2)
+ blocks.first.should eql({:args => [nil], :block => @block})
+ blocks.last.should eql({:args => [:stats], :block => @block2})
+ end
+ end
+
+ end
+
+ describe "inheritance" do
+ before :each do
+ klass = DesignModel.dup
+ klass.design do
+ view :by_name
+ end
+ @klass = Class.new(klass)
+ end
+
+ it "should add designs to sub module" do
+ @klass.should respond_to(:design_doc)
end
end

0 comments on commit 1796e63

Please sign in to comment.