Adding configuration support and changing 'couchrest-type' key to 'model' along with config options
This commit is contained in:
parent
5c21de8586
commit
85cd1308bc
|
@ -1,6 +1,8 @@
|
|||
== Next Version
|
||||
|
||||
* Major enhancements
|
||||
* IMPORTANT: Model's class name key changed from 'couchrest-type' to 'model'
|
||||
* Support for configuration module and "model_type_key" option for overriding model's type key
|
||||
|
||||
* Minor enhancements
|
||||
* Fixing find("") issue (thanks epochwolf)
|
||||
|
|
|
@ -4,6 +4,7 @@ module CouchRest
|
|||
|
||||
extend ActiveModel::Naming
|
||||
|
||||
include CouchRest::Model::Configuration
|
||||
include CouchRest::Model::Persistence
|
||||
include CouchRest::Model::Callbacks
|
||||
include CouchRest::Model::DocumentQueries
|
||||
|
@ -37,7 +38,7 @@ module CouchRest
|
|||
|
||||
# Accessors
|
||||
attr_accessor :casted_by
|
||||
|
||||
|
||||
|
||||
# Instantiate a new CouchRest::Model::Base by preparing all properties
|
||||
# using the provided document hash.
|
||||
|
@ -50,7 +51,7 @@ module CouchRest
|
|||
prepare_all_attributes(doc, options)
|
||||
super(doc)
|
||||
unless self['_id'] && self['_rev']
|
||||
self['couchrest-type'] = self.class.to_s
|
||||
self[self.model_type_key] = self.class.to_s
|
||||
end
|
||||
after_initialize if respond_to?(:after_initialize)
|
||||
end
|
||||
|
|
49
lib/couchrest/model/configuration.rb
Normal file
49
lib/couchrest/model/configuration.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
module CouchRest
|
||||
|
||||
# CouchRest Model Configuration support, stolen from Carrierwave by jnicklas
|
||||
# http://github.com/jnicklas/carrierwave/blob/master/lib/carrierwave/uploader/configuration.rb
|
||||
|
||||
module Model
|
||||
module Configuration
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
add_config :model_type_key
|
||||
|
||||
configure do |config|
|
||||
config.model_type_key = 'model'
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
def add_config(name)
|
||||
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||
def self.#{name}(value=nil)
|
||||
@#{name} = value if value
|
||||
return @#{name} if self.object_id == #{self.object_id} || defined?(@#{name})
|
||||
name = superclass.#{name}
|
||||
return nil if name.nil? && !instance_variable_defined?("@#{name}")
|
||||
@#{name} = name && !name.is_a?(Module) && !name.is_a?(Symbol) && !name.is_a?(Numeric) && !name.is_a?(TrueClass) && !name.is_a?(FalseClass) ? name.dup : name
|
||||
end
|
||||
|
||||
def self.#{name}=(value)
|
||||
@#{name} = value
|
||||
end
|
||||
|
||||
def #{name}
|
||||
self.class.#{name}
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def configure
|
||||
yield self
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ module CouchRest
|
|||
"views" => {
|
||||
'all' => {
|
||||
'map' => "function(doc) {
|
||||
if (doc['couchrest-type'] == '#{self.to_s}') {
|
||||
if (doc['#{self.model_type_key}'] == '#{self.to_s}') {
|
||||
emit(doc['_id'],1);
|
||||
}
|
||||
}"
|
||||
|
|
|
@ -8,21 +8,21 @@ module CouchRest
|
|||
|
||||
module ClassMethods
|
||||
|
||||
# Load all documents that have the "couchrest-type" field equal to the
|
||||
# Load all documents that have the model_type_key's field equal to the
|
||||
# name of the current class. Take the standard set of
|
||||
# CouchRest::Database#view options.
|
||||
def all(opts = {}, &block)
|
||||
view(:all, opts, &block)
|
||||
end
|
||||
|
||||
# Returns the number of documents that have the "couchrest-type" field
|
||||
# Returns the number of documents that have the model_type_key's field
|
||||
# equal to the name of the current class. Takes the standard set of
|
||||
# CouchRest::Database#view options
|
||||
def count(opts = {}, &block)
|
||||
all({:raw => true, :limit => 0}.merge(opts), &block)['total_rows']
|
||||
end
|
||||
|
||||
# Load the first document that have the "couchrest-type" field equal to
|
||||
# Load the first document that have the model_type_key's field equal to
|
||||
# the name of the current class.
|
||||
#
|
||||
# ==== Returns
|
||||
|
|
|
@ -97,7 +97,7 @@ module CouchRest
|
|||
# ==== Returns
|
||||
# a document instance
|
||||
def create_from_database(doc = {})
|
||||
base = (doc['couchrest-type'].blank? || doc['couchrest-type'] == self.to_s) ? self : doc['couchrest-type'].constantize
|
||||
base = (doc[model_type_key].blank? || doc[model_type_key] == self.to_s) ? self : doc[model_type_key].constantize
|
||||
base.new(doc, :directly_set_attributes => true)
|
||||
end
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ module CouchRest
|
|||
# view_by :tags,
|
||||
# :map =>
|
||||
# "function(doc) {
|
||||
# if (doc['couchrest-type'] == 'Post' && doc.tags) {
|
||||
# if (doc['model'] == 'Post' && doc.tags) {
|
||||
# doc.tags.forEach(function(tag){
|
||||
# emit(doc.tag, 1);
|
||||
# });
|
||||
|
@ -39,7 +39,7 @@ module CouchRest
|
|||
# function:
|
||||
#
|
||||
# function(doc) {
|
||||
# if (doc['couchrest-type'] == 'Post' && doc.date) {
|
||||
# if (doc['model'] == 'Post' && doc.date) {
|
||||
# emit(doc.date, null);
|
||||
# }
|
||||
# }
|
||||
|
@ -77,7 +77,7 @@ module CouchRest
|
|||
ducktype = opts.delete(:ducktype)
|
||||
unless ducktype || opts[:map]
|
||||
opts[:guards] ||= []
|
||||
opts[:guards].push "(doc['couchrest-type'] == '#{self.to_s}')"
|
||||
opts[:guards].push "(doc['#{model_type_key}'] == '#{self.to_s}')"
|
||||
end
|
||||
keys.push opts
|
||||
design_doc.view_by(*keys)
|
||||
|
|
|
@ -48,6 +48,7 @@ require "couchrest/model/collection"
|
|||
require "couchrest/model/attribute_protection"
|
||||
require "couchrest/model/attributes"
|
||||
require "couchrest/model/associations"
|
||||
require "couchrest/model/configuration"
|
||||
|
||||
# Monkey patches applied to couchrest
|
||||
require "couchrest/model/support/couchrest"
|
||||
|
|
|
@ -150,7 +150,7 @@ describe "Model Attributes" do
|
|||
it "Base#all should not strip protected attributes" do
|
||||
# all creates a CollectionProxy
|
||||
docs = WithProtected.all(:key => @user.id)
|
||||
docs.size.should == 1
|
||||
docs.length.should == 1
|
||||
reloaded = docs.first
|
||||
verify_attrs reloaded
|
||||
end
|
||||
|
|
|
@ -36,7 +36,7 @@ describe "Model Base" do
|
|||
|
||||
it "should not failed on a nil value in argument" do
|
||||
@obj = Basic.new(nil)
|
||||
@obj.should == { 'couchrest-type' => 'Basic' }
|
||||
@obj.should_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
87
spec/couchrest/configuration_spec.rb
Normal file
87
spec/couchrest/configuration_spec.rb
Normal file
|
@ -0,0 +1,87 @@
|
|||
# encoding: utf-8
|
||||
require File.expand_path('../../spec_helper', __FILE__)
|
||||
require File.join(FIXTURE_PATH, 'more', 'cat')
|
||||
|
||||
describe CouchRest::Model::Base do
|
||||
|
||||
before do
|
||||
@class = Class.new(CouchRest::Model::Base)
|
||||
end
|
||||
|
||||
describe '.configure' do
|
||||
it "should set a configuration parameter" do
|
||||
@class.add_config :foo_bar
|
||||
@class.configure do |config|
|
||||
config.foo_bar = 'monkey'
|
||||
end
|
||||
@class.foo_bar.should == 'monkey'
|
||||
end
|
||||
end
|
||||
|
||||
describe '.add_config' do
|
||||
|
||||
it "should add a class level accessor" do
|
||||
@class.add_config :foo_bar
|
||||
@class.foo_bar = 'foo'
|
||||
@class.foo_bar.should == 'foo'
|
||||
end
|
||||
|
||||
['foo', :foo, 45, ['foo', :bar]].each do |val|
|
||||
it "should be inheritable for a #{val.class}" do
|
||||
@class.add_config :foo_bar
|
||||
@child_class = Class.new(@class)
|
||||
|
||||
@class.foo_bar = val
|
||||
@class.foo_bar.should == val
|
||||
@child_class.foo_bar.should == val
|
||||
|
||||
@child_class.foo_bar = "bar"
|
||||
@child_class.foo_bar.should == "bar"
|
||||
|
||||
@class.foo_bar.should == val
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
it "should add an instance level accessor" do
|
||||
@class.add_config :foo_bar
|
||||
@class.foo_bar = 'foo'
|
||||
@class.new.foo_bar.should == 'foo'
|
||||
end
|
||||
|
||||
it "should add a convenient in-class setter" do
|
||||
@class.add_config :foo_bar
|
||||
@class.foo_bar "monkey"
|
||||
@class.foo_bar.should == "monkey"
|
||||
end
|
||||
end
|
||||
|
||||
describe "General examples" do
|
||||
|
||||
before(:all) do
|
||||
@default_model_key = 'model'
|
||||
end
|
||||
|
||||
it "should set default configuration options on Model::Base" do
|
||||
CouchRest::Model::Base.model_type_key.should eql(@default_model_key)
|
||||
end
|
||||
|
||||
it "should provide options from instance" do
|
||||
cat = Cat.new
|
||||
cat.model_type_key.should eql(@default_model_key)
|
||||
end
|
||||
|
||||
it "should be possible to override on class using configure method" do
|
||||
Cat.instance_eval do
|
||||
configure do |config|
|
||||
config.model_type_key = 'cat-type'
|
||||
end
|
||||
end
|
||||
CouchRest::Model::Base.model_type_key.should eql(@default_model_key)
|
||||
Cat.model_type_key.should eql('cat-type')
|
||||
cat = Cat.new
|
||||
cat.model_type_key.should eql('cat-type')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -25,7 +25,7 @@ describe "Model Persistence" do
|
|||
end
|
||||
|
||||
it "should instantialize document of different type" do
|
||||
doc = Article.create_from_database({'_id' => 'testitem2', '_rev' => 123, 'couchrest-type' => 'WithTemplateAndUniqueID', 'name' => 'my test'})
|
||||
doc = Article.create_from_database({'_id' => 'testitem2', '_rev' => 123, Article.model_type_key => 'WithTemplateAndUniqueID', 'name' => 'my test'})
|
||||
doc.class.should eql(WithTemplateAndUniqueID)
|
||||
end
|
||||
|
||||
|
@ -114,7 +114,7 @@ describe "Model Persistence" do
|
|||
end
|
||||
|
||||
it "should set the type" do
|
||||
@sobj['couchrest-type'].should == 'Basic'
|
||||
@sobj[@sobj.model_type_key].should == 'Basic'
|
||||
end
|
||||
|
||||
it "should accept true or false on save for validation" do
|
||||
|
|
|
@ -92,8 +92,8 @@ describe "Subclassing a Model" do
|
|||
OnlineCourse.design_doc['views'].keys.should_not include('by_title')
|
||||
end
|
||||
|
||||
it "should have an all view with a guard clause for couchrest-type == subclass name in the map function" do
|
||||
OnlineCourse.design_doc['views']['all']['map'].should =~ /if \(doc\['couchrest-type'\] == 'OnlineCourse'\)/
|
||||
it "should have an all view with a guard clause for model == subclass name in the map function" do
|
||||
OnlineCourse.design_doc['views']['all']['map'].should =~ /if \(doc\['model'\] == 'OnlineCourse'\)/
|
||||
end
|
||||
end
|
||||
|
||||
|
|
2
spec/fixtures/more/article.rb
vendored
2
spec/fixtures/more/article.rb
vendored
|
@ -9,7 +9,7 @@ class Article < CouchRest::Model::Base
|
|||
view_by :tags,
|
||||
:map =>
|
||||
"function(doc) {
|
||||
if (doc['couchrest-type'] == 'Article' && doc.tags) {
|
||||
if (doc['#{model_type_key}'] == 'Article' && doc.tags) {
|
||||
doc.tags.forEach(function(tag){
|
||||
emit(tag, 1);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue