couchrest_model 1.1.2 → 1.2.0.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|