couchrest_model 1.1.2 → 1.2.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +8 -2
- data/VERSION +1 -1
- data/couchrest_model.gemspec +2 -1
- data/history.md +8 -0
- data/lib/couchrest/model/base.rb +0 -20
- data/lib/couchrest/model/configuration.rb +2 -0
- data/lib/couchrest/model/core_extensions/time_parsing.rb +35 -9
- data/lib/couchrest/model/designs/design.rb +182 -0
- data/lib/couchrest/model/designs/view.rb +91 -48
- data/lib/couchrest/model/designs.rb +72 -19
- data/lib/couchrest/model/document_queries.rb +15 -45
- data/lib/couchrest/model/properties.rb +43 -2
- data/lib/couchrest/model/proxyable.rb +20 -54
- data/lib/couchrest/model/typecast.rb +1 -1
- data/lib/couchrest/model/validations/uniqueness.rb +7 -6
- data/lib/couchrest_model.rb +1 -5
- data/spec/fixtures/models/article.rb +22 -20
- data/spec/fixtures/models/base.rb +15 -7
- data/spec/fixtures/models/course.rb +7 -4
- data/spec/fixtures/models/project.rb +4 -1
- data/spec/fixtures/models/sale_entry.rb +5 -3
- data/spec/unit/base_spec.rb +51 -5
- data/spec/unit/core_extensions/time_parsing.rb +41 -0
- data/spec/unit/designs/design_spec.rb +291 -0
- data/spec/unit/designs/view_spec.rb +135 -40
- data/spec/unit/designs_spec.rb +341 -30
- data/spec/unit/dirty_spec.rb +67 -0
- data/spec/unit/inherited_spec.rb +2 -2
- data/spec/unit/property_protection_spec.rb +3 -1
- data/spec/unit/property_spec.rb +43 -3
- data/spec/unit/proxyable_spec.rb +57 -98
- data/spec/unit/subclass_spec.rb +14 -5
- data/spec/unit/validations_spec.rb +14 -12
- metadata +172 -129
- data/lib/couchrest/model/class_proxy.rb +0 -135
- data/lib/couchrest/model/collection.rb +0 -273
- data/lib/couchrest/model/design_doc.rb +0 -115
- data/lib/couchrest/model/support/couchrest_design.rb +0 -33
- data/lib/couchrest/model/views.rb +0 -148
- data/spec/unit/class_proxy_spec.rb +0 -167
- data/spec/unit/collection_spec.rb +0 -86
- data/spec/unit/design_doc_spec.rb +0 -212
- data/spec/unit/view_spec.rb +0 -352
@@ -19,15 +19,32 @@ module CouchRest
|
|
19
19
|
module Designs
|
20
20
|
extend ActiveSupport::Concern
|
21
21
|
|
22
|
+
|
22
23
|
module ClassMethods
|
23
24
|
|
24
25
|
# Add views and other design document features
|
25
26
|
# to the current model.
|
26
|
-
def design(
|
27
|
-
|
28
|
-
|
27
|
+
def design(prefix = nil, &block)
|
28
|
+
|
29
|
+
# Store ourselves a copy of this design spec incase any other model inherits.
|
30
|
+
(@_design_blocks ||= [ ]) << {:args => [prefix], :block => block}
|
29
31
|
|
32
|
+
mapper = DesignMapper.new(self, prefix)
|
30
33
|
mapper.instance_eval(&block) if block_given?
|
34
|
+
|
35
|
+
# Create an 'all' view if no prefix and one has not been defined already
|
36
|
+
mapper.view(:all) if prefix.nil? and !mapper.design_doc.has_view?(:all)
|
37
|
+
end
|
38
|
+
|
39
|
+
def inherited(model)
|
40
|
+
super
|
41
|
+
|
42
|
+
# Go through our design blocks and re-implement them in the child.
|
43
|
+
unless @_design_blocks.nil?
|
44
|
+
@_design_blocks.each do |row|
|
45
|
+
model.design(*row[:args], &row[:block])
|
46
|
+
end
|
47
|
+
end
|
31
48
|
end
|
32
49
|
|
33
50
|
# Override the default page pagination value:
|
@@ -47,22 +64,43 @@ module CouchRest
|
|
47
64
|
@_default_per_page || 25
|
48
65
|
end
|
49
66
|
|
67
|
+
def design_docs
|
68
|
+
@_design_docs ||= []
|
69
|
+
end
|
70
|
+
|
50
71
|
end
|
51
72
|
|
52
|
-
#
|
73
|
+
# Map method calls defined in a design block to actions
|
74
|
+
# in the Design Document.
|
53
75
|
class DesignMapper
|
54
76
|
|
55
|
-
|
77
|
+
# Basic mapper attributes
|
78
|
+
attr_accessor :model, :method, :prefix
|
56
79
|
|
57
|
-
|
58
|
-
|
80
|
+
# Temporary variable storing the design doc
|
81
|
+
attr_accessor :design_doc
|
82
|
+
|
83
|
+
def initialize(model, prefix = nil)
|
84
|
+
self.model = model
|
85
|
+
self.prefix = prefix
|
86
|
+
self.method = Design.method_name(prefix)
|
87
|
+
|
88
|
+
create_model_design_doc_reader
|
89
|
+
self.design_doc = model.send(method) || assign_model_design_doc
|
59
90
|
end
|
60
91
|
|
61
|
-
|
62
|
-
|
92
|
+
def disable_auto_update
|
93
|
+
design_doc.auto_update = false
|
94
|
+
end
|
95
|
+
|
96
|
+
def enable_auto_update
|
97
|
+
design_doc.auto_update = true
|
98
|
+
end
|
99
|
+
|
100
|
+
# Add the specified view to the design doc the definition was made in
|
101
|
+
# and create quick access methods in the model.
|
63
102
|
def view(name, opts = {})
|
64
|
-
|
65
|
-
create_view_method(name)
|
103
|
+
design_doc.create_view(name, opts)
|
66
104
|
end
|
67
105
|
|
68
106
|
# Really simple design function that allows a filter
|
@@ -72,16 +110,31 @@ module CouchRest
|
|
72
110
|
# No methods are created here, the design is simply updated.
|
73
111
|
# See the CouchDB API for more information on how to use this.
|
74
112
|
def filter(name, function)
|
75
|
-
|
76
|
-
filters[name.to_s] = function
|
113
|
+
design_doc.create_filter(name, function)
|
77
114
|
end
|
78
115
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
116
|
+
# Convenience wrapper to access model's type key option.
|
117
|
+
def model_type_key
|
118
|
+
model.model_type_key
|
119
|
+
end
|
120
|
+
|
121
|
+
protected
|
122
|
+
|
123
|
+
# Create accessor in model and assign a new design doc.
|
124
|
+
# New design doc is returned ready to use.
|
125
|
+
def create_model_design_doc_reader
|
126
|
+
model.instance_eval "def #{method}; @#{method}; end"
|
127
|
+
end
|
128
|
+
|
129
|
+
def assign_model_design_doc
|
130
|
+
doc = Design.new(model, prefix)
|
131
|
+
model.instance_variable_set("@#{method}", doc)
|
132
|
+
model.design_docs << doc
|
133
|
+
|
134
|
+
# Set defaults
|
135
|
+
doc.auto_update = model.auto_update_design_doc
|
136
|
+
|
137
|
+
doc
|
85
138
|
end
|
86
139
|
|
87
140
|
end
|
@@ -5,52 +5,22 @@ module CouchRest
|
|
5
5
|
|
6
6
|
module ClassMethods
|
7
7
|
|
8
|
-
#
|
9
|
-
#
|
10
|
-
|
11
|
-
|
12
|
-
view(:all, opts, &block)
|
8
|
+
# Wrapper for the master design documents all method to provide
|
9
|
+
# a total count of entries.
|
10
|
+
def count
|
11
|
+
all.count
|
13
12
|
end
|
14
|
-
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
def count(opts = {}, &block)
|
19
|
-
all({:raw => true, :limit => 0}.merge(opts), &block)['total_rows']
|
20
|
-
end
|
21
|
-
|
22
|
-
# Load the first document that have the model_type_key's field equal to
|
23
|
-
# the name of the current class.
|
24
|
-
#
|
25
|
-
# ==== Returns
|
26
|
-
# Object:: The first object instance available
|
27
|
-
# or
|
28
|
-
# Nil:: if no instances available
|
29
|
-
#
|
30
|
-
# ==== Parameters
|
31
|
-
# opts<Hash>::
|
32
|
-
# View options, see <tt>CouchRest::Database#view</tt> options for more info.
|
33
|
-
def first(opts = {})
|
34
|
-
first_instance = self.all(opts.merge!(:limit => 1))
|
35
|
-
first_instance.empty? ? nil : first_instance.first
|
13
|
+
|
14
|
+
# Wrapper for the master design document's first method on all view.
|
15
|
+
def first
|
16
|
+
all.first
|
36
17
|
end
|
37
|
-
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
# ==== Returns
|
43
|
-
# Object:: The last object instance available
|
44
|
-
# or
|
45
|
-
# Nil:: if no instances available
|
46
|
-
#
|
47
|
-
# ==== Parameters
|
48
|
-
# opts<Hash>::
|
49
|
-
# View options, see <tt>CouchRest::Database#view</tt> options for more info.
|
50
|
-
def last(opts = {})
|
51
|
-
first(opts.merge!(:descending => true))
|
18
|
+
|
19
|
+
# Wrapper for the master design document's last method on all view.
|
20
|
+
def last
|
21
|
+
all.last
|
52
22
|
end
|
53
|
-
|
23
|
+
|
54
24
|
# Load a document from the database by id
|
55
25
|
# No exceptions will be raised if the document isn't found
|
56
26
|
#
|
@@ -91,9 +61,9 @@ module CouchRest
|
|
91
61
|
raise CouchRest::Model::DocumentNotFound
|
92
62
|
end
|
93
63
|
alias :find! :get!
|
94
|
-
|
64
|
+
|
95
65
|
end
|
96
|
-
|
66
|
+
|
97
67
|
end
|
98
68
|
end
|
99
69
|
end
|
@@ -106,13 +106,22 @@ module CouchRest
|
|
106
106
|
# that have not been accepted.
|
107
107
|
def directly_set_attributes(hash, mass_assign = false)
|
108
108
|
return if hash.nil?
|
109
|
+
|
110
|
+
multi_parameter_attributes = []
|
111
|
+
|
109
112
|
hash.reject do |key, value|
|
110
|
-
if
|
111
|
-
|
113
|
+
if key.to_s.include?("(")
|
114
|
+
multi_parameter_attributes << [ key, value ]
|
115
|
+
false
|
116
|
+
elsif self.respond_to?("#{key}=")
|
117
|
+
self.send("#{key}=", value)
|
112
118
|
elsif mass_assign || mass_assign_any_attribute
|
119
|
+
couchrest_attribute_will_change!(key) if use_dirty? && self[key] != value
|
113
120
|
self[key] = value
|
114
121
|
end
|
115
122
|
end
|
123
|
+
|
124
|
+
assign_multiparameter_attributes(multi_parameter_attributes, hash) unless multi_parameter_attributes.empty?
|
116
125
|
end
|
117
126
|
|
118
127
|
def directly_set_read_only_attributes(hash)
|
@@ -125,7 +134,39 @@ module CouchRest
|
|
125
134
|
end
|
126
135
|
end
|
127
136
|
|
137
|
+
def assign_multiparameter_attributes(pairs, hash)
|
138
|
+
execute_callstack_for_multiparameter_attributes(
|
139
|
+
extract_callstack_for_multiparameter_attributes(pairs), hash
|
140
|
+
)
|
141
|
+
end
|
142
|
+
def execute_callstack_for_multiparameter_attributes(callstack, hash)
|
143
|
+
callstack.each do |name, values_with_empty_parameters|
|
144
|
+
if self.respond_to?("#{name}=")
|
145
|
+
casted_attrib = send("#{name}=", values_with_empty_parameters)
|
146
|
+
unless casted_attrib.is_a?(Hash)
|
147
|
+
hash.reject { |key, value| key.include?(name.to_s)}
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
hash
|
152
|
+
end
|
153
|
+
|
154
|
+
def extract_callstack_for_multiparameter_attributes(pairs)
|
155
|
+
attributes = { }
|
156
|
+
|
157
|
+
pairs.each do |pair|
|
158
|
+
multiparameter_name, value = pair
|
159
|
+
attribute_name = multiparameter_name.split("(").first
|
160
|
+
attributes[attribute_name] = {} unless attributes.include?(attribute_name)
|
161
|
+
attributes[attribute_name][find_parameter_name(multiparameter_name)] ||= value
|
162
|
+
end
|
163
|
+
attributes
|
164
|
+
end
|
128
165
|
|
166
|
+
def find_parameter_name(multiparameter_name)
|
167
|
+
position = multiparameter_name.scan(/\(([0-9]*).*\)/).first.first.to_i
|
168
|
+
{1 => :year, 2 => :month, 3 => :day, 4 => :hour, 5 => :min, 6 => :sec}[position]
|
169
|
+
end
|
129
170
|
|
130
171
|
module ClassMethods
|
131
172
|
|
@@ -70,6 +70,8 @@ module CouchRest
|
|
70
70
|
@owner = owner
|
71
71
|
@owner_name = owner_name
|
72
72
|
@database = database
|
73
|
+
|
74
|
+
create_view_methods
|
73
75
|
end
|
74
76
|
|
75
77
|
# Base
|
@@ -81,39 +83,18 @@ module CouchRest
|
|
81
83
|
proxy_block_update(:build_from_database, attrs, options, &block)
|
82
84
|
end
|
83
85
|
|
84
|
-
|
85
|
-
if has_view?(m)
|
86
|
-
if model.respond_to?(m)
|
87
|
-
return model.send(m, *args).proxy(self)
|
88
|
-
else
|
89
|
-
query = args.shift || {}
|
90
|
-
return view(m, query, *args, &block)
|
91
|
-
end
|
92
|
-
elsif m.to_s =~ /^find_(by_.+)/
|
93
|
-
view_name = $1
|
94
|
-
if has_view?(view_name)
|
95
|
-
return first_from_view(view_name, *args)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
super
|
99
|
-
end
|
100
|
-
|
101
|
-
# DocumentQueries
|
102
|
-
|
103
|
-
def all(opts = {}, &block)
|
104
|
-
proxy_update_all(@model.all({:database => @database}.merge(opts), &block))
|
105
|
-
end
|
86
|
+
# From DocumentQueries (The old fashioned way)
|
106
87
|
|
107
88
|
def count(opts = {})
|
108
|
-
|
89
|
+
all(opts).count
|
109
90
|
end
|
110
91
|
|
111
92
|
def first(opts = {})
|
112
|
-
|
93
|
+
all(opts).first
|
113
94
|
end
|
114
95
|
|
115
96
|
def last(opts = {})
|
116
|
-
|
97
|
+
all(opts).last
|
117
98
|
end
|
118
99
|
|
119
100
|
def get(id)
|
@@ -121,38 +102,23 @@ module CouchRest
|
|
121
102
|
end
|
122
103
|
alias :find :get
|
123
104
|
|
124
|
-
|
125
|
-
|
126
|
-
def has_view?(view)
|
127
|
-
@model.has_view?(view)
|
128
|
-
end
|
129
|
-
|
130
|
-
def view_by(*args)
|
131
|
-
@model.view_by(*args)
|
132
|
-
end
|
133
|
-
|
134
|
-
def view(name, query={}, &block)
|
135
|
-
proxy_update_all(@model.view(name, {:database => @database}.merge(query), &block))
|
136
|
-
end
|
137
|
-
|
138
|
-
def first_from_view(name, *args)
|
139
|
-
# add to first hash available, or add to end
|
140
|
-
(args.last.is_a?(Hash) ? args.last : (args << {}).last)[:database] = @database
|
141
|
-
proxy_update(@model.first_from_view(name, *args))
|
142
|
-
end
|
143
|
-
|
144
|
-
# DesignDoc
|
145
|
-
def design_doc
|
146
|
-
@model.design_doc
|
147
|
-
end
|
105
|
+
protected
|
148
106
|
|
149
|
-
def
|
150
|
-
|
107
|
+
def create_view_methods
|
108
|
+
model.design_docs.each do |doc|
|
109
|
+
doc.view_names.each do |name|
|
110
|
+
class_eval <<-EOS, __FILE__, __LINE__ + 1
|
111
|
+
def #{name}(opts = {})
|
112
|
+
model.#{name}({:proxy => self}.merge(opts))
|
113
|
+
end
|
114
|
+
def find_#{name}(*key)
|
115
|
+
#{name}.key(*key).first()
|
116
|
+
end
|
117
|
+
EOS
|
118
|
+
end
|
119
|
+
end
|
151
120
|
end
|
152
121
|
|
153
|
-
|
154
|
-
protected
|
155
|
-
|
156
122
|
# Update the document's proxy details, specifically, the fields that
|
157
123
|
# link back to the original document.
|
158
124
|
def proxy_update(doc)
|
@@ -123,7 +123,7 @@ module CouchRest
|
|
123
123
|
|
124
124
|
# Creates a Date instance from a Hash with keys :year, :month, :day
|
125
125
|
def typecast_hash_to_date(value)
|
126
|
-
Date.new(*extract_time(value)[0, 3])
|
126
|
+
Date.new(*extract_time(value)[0, 3].map(&:to_i))
|
127
127
|
end
|
128
128
|
|
129
129
|
# Creates a Time instance from a Hash with keys :year, :month, :day,
|
@@ -15,9 +15,10 @@ module CouchRest
|
|
15
15
|
attributes.each do |attribute|
|
16
16
|
opts = merge_view_options(attribute)
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
unless model.respond_to?(opts[:view_name])
|
19
|
+
model.design do
|
20
|
+
view opts[:view_name], :allow_nil => true
|
21
|
+
end
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -33,15 +34,15 @@ module CouchRest
|
|
33
34
|
# Determine the base of the search
|
34
35
|
base = opts[:proxy].nil? ? model : document.instance_eval(opts[:proxy])
|
35
36
|
|
36
|
-
|
37
|
+
unless base.respond_to?(opts[:view_name])
|
37
38
|
raise "View #{document.class.name}.#{opts[:view_name]} does not exist for validation!"
|
38
39
|
end
|
39
40
|
|
40
|
-
rows = base.
|
41
|
+
rows = base.send(opts[:view_name], :key => values, :limit => 2, :include_docs => false).rows
|
41
42
|
return if rows.empty?
|
42
43
|
|
43
44
|
unless document.new?
|
44
|
-
return if rows.find{|row| row
|
45
|
+
return if rows.find{|row| row.id == document.id}
|
45
46
|
end
|
46
47
|
|
47
48
|
if rows.length > 0
|
data/lib/couchrest_model.rb
CHANGED
@@ -36,20 +36,16 @@ require "couchrest/model/casted_hash"
|
|
36
36
|
require "couchrest/model/validations"
|
37
37
|
require "couchrest/model/callbacks"
|
38
38
|
require "couchrest/model/document_queries"
|
39
|
-
require "couchrest/model/views"
|
40
|
-
require "couchrest/model/design_doc"
|
41
39
|
require "couchrest/model/extended_attachments"
|
42
|
-
require "couchrest/model/class_proxy"
|
43
40
|
require "couchrest/model/proxyable"
|
44
|
-
require "couchrest/model/collection"
|
45
41
|
require "couchrest/model/associations"
|
46
42
|
require "couchrest/model/configuration"
|
47
43
|
require "couchrest/model/connection"
|
48
44
|
require "couchrest/model/designs"
|
45
|
+
require "couchrest/model/designs/design"
|
49
46
|
require "couchrest/model/designs/view"
|
50
47
|
|
51
48
|
# Monkey patches applied to couchrest
|
52
|
-
require "couchrest/model/support/couchrest_design"
|
53
49
|
require "couchrest/model/support/couchrest_database"
|
54
50
|
|
55
51
|
# Core Extensions
|
@@ -1,24 +1,26 @@
|
|
1
1
|
class Article < CouchRest::Model::Base
|
2
2
|
use_database DB
|
3
3
|
unique_id :slug
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
4
|
+
|
5
|
+
design do
|
6
|
+
view :by_date # Default options not supported: :descending => true
|
7
|
+
view :by_user_id_and_date
|
8
|
+
|
9
|
+
view :by_tags,
|
10
|
+
:map =>
|
11
|
+
"function(doc) {
|
12
|
+
if (doc['#{model.model_type_key}'] == 'Article' && doc.tags) {
|
13
|
+
doc.tags.forEach(function(tag){
|
14
|
+
emit(tag, 1);
|
15
|
+
});
|
16
|
+
}
|
17
|
+
}",
|
18
|
+
:reduce =>
|
19
|
+
"function(keys, values, rereduce) {
|
20
|
+
return sum(values);
|
21
|
+
}"
|
22
|
+
|
23
|
+
end
|
22
24
|
|
23
25
|
property :date, Date
|
24
26
|
property :slug, :read_only => true
|
@@ -27,9 +29,9 @@ class Article < CouchRest::Model::Base
|
|
27
29
|
property :tags, [String]
|
28
30
|
|
29
31
|
timestamps!
|
30
|
-
|
32
|
+
|
31
33
|
before_save :generate_slug_from_title
|
32
|
-
|
34
|
+
|
33
35
|
def generate_slug_from_title
|
34
36
|
self['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'') if new?
|
35
37
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class WithDefaultValues < CouchRest::Model::Base
|
2
|
-
use_database
|
2
|
+
use_database DB
|
3
3
|
property :preset, Object, :default => {:right => 10, :top_align => false}
|
4
4
|
property :set_by_proc, Time, :default => Proc.new{Time.now}
|
5
5
|
property :tags, [String], :default => []
|
@@ -10,7 +10,7 @@ class WithDefaultValues < CouchRest::Model::Base
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class WithSimplePropertyType < CouchRest::Model::Base
|
13
|
-
use_database
|
13
|
+
use_database DB
|
14
14
|
property :name, String
|
15
15
|
property :preset, String, :default => 'none'
|
16
16
|
property :tags, [String]
|
@@ -18,7 +18,7 @@ class WithSimplePropertyType < CouchRest::Model::Base
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class WithCallBacks < CouchRest::Model::Base
|
21
|
-
use_database
|
21
|
+
use_database DB
|
22
22
|
property :name
|
23
23
|
property :run_before_validation
|
24
24
|
property :run_after_validation
|
@@ -85,27 +85,30 @@ end
|
|
85
85
|
|
86
86
|
# Following two fixture classes have __intentionally__ diffent syntax for setting the validation context
|
87
87
|
class WithContextualValidationOnCreate < CouchRest::Model::Base
|
88
|
+
use_database DB
|
88
89
|
property(:name, String)
|
89
90
|
validates(:name, :presence => {:on => :create})
|
90
91
|
end
|
91
92
|
|
92
93
|
class WithContextualValidationOnUpdate < CouchRest::Model::Base
|
94
|
+
use_database DB
|
93
95
|
property(:name, String)
|
94
96
|
validates(:name, :presence => true, :on => :update)
|
95
97
|
end
|
96
98
|
|
97
99
|
class WithTemplateAndUniqueID < CouchRest::Model::Base
|
98
|
-
use_database
|
100
|
+
use_database DB
|
99
101
|
unique_id do |model|
|
100
102
|
model.slug
|
101
103
|
end
|
102
104
|
property :slug
|
103
105
|
property :preset, :default => 'value'
|
104
106
|
property :has_no_default
|
107
|
+
design
|
105
108
|
end
|
106
109
|
|
107
110
|
class WithGetterAndSetterMethods < CouchRest::Model::Base
|
108
|
-
use_database
|
111
|
+
use_database DB
|
109
112
|
|
110
113
|
property :other_arg
|
111
114
|
def arg
|
@@ -118,7 +121,7 @@ class WithGetterAndSetterMethods < CouchRest::Model::Base
|
|
118
121
|
end
|
119
122
|
|
120
123
|
class WithAfterInitializeMethod < CouchRest::Model::Base
|
121
|
-
use_database
|
124
|
+
use_database DB
|
122
125
|
|
123
126
|
property :some_value
|
124
127
|
|
@@ -147,6 +150,7 @@ class WithUniqueValidationView < CouchRest::Model::Base
|
|
147
150
|
end
|
148
151
|
property :title
|
149
152
|
|
153
|
+
design
|
150
154
|
validates_uniqueness_of :code, :view => 'all'
|
151
155
|
end
|
152
156
|
|
@@ -159,4 +163,8 @@ class WithScopedUniqueValidation < CouchRest::Model::Base
|
|
159
163
|
validates_uniqueness_of :title, :scope => :parent_id
|
160
164
|
end
|
161
165
|
|
162
|
-
|
166
|
+
class WithDateAndTime < CouchRest::Model::Base
|
167
|
+
use_database DB
|
168
|
+
property :exec_date, Date
|
169
|
+
property :exec_time, Time
|
170
|
+
end
|
@@ -18,10 +18,13 @@ class Course < CouchRest::Model::Base
|
|
18
18
|
property :very_active, :type => TrueClass
|
19
19
|
property :klass, :type => Class
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
design do
|
22
|
+
view :by_title
|
23
|
+
view :by_title_and_active
|
24
24
|
|
25
|
-
|
25
|
+
view :by_dept, :ducktype => true
|
26
|
+
|
27
|
+
view :by_active, :map => "function(d) { if (d['#{model_type_key}'] == 'Course' && d['active']) { emit(d['updated_at'], 1); }}", :reduce => "function(k,v,r) { return sum(v); }"
|
28
|
+
end
|
26
29
|
|
27
30
|
end
|