mongomodel 0.3.3 → 0.3.4
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/Appraisals +9 -0
- data/Gemfile +2 -2
- data/Rakefile +23 -13
- data/gemfiles/rails-3.0.gemfile +10 -0
- data/gemfiles/rails-3.0.gemfile.lock +73 -0
- data/gemfiles/rails-3.1.gemfile +10 -0
- data/gemfiles/rails-3.1.gemfile.lock +83 -0
- data/lib/mongomodel.rb +0 -1
- data/lib/mongomodel/concerns/abstract_class.rb +1 -0
- data/lib/mongomodel/concerns/associations.rb +12 -3
- data/lib/mongomodel/concerns/associations/base/definition.rb +5 -3
- data/lib/mongomodel/concerns/attribute_methods.rb +14 -7
- data/lib/mongomodel/concerns/properties.rb +15 -4
- data/lib/mongomodel/document/indexes.rb +14 -5
- data/lib/mongomodel/document/persistence.rb +7 -5
- data/lib/mongomodel/document/scopes.rb +22 -8
- data/lib/mongomodel/railtie.rb +2 -3
- data/lib/mongomodel/support/collection.rb +3 -1
- data/lib/mongomodel/support/map.rb +4 -2
- data/lib/mongomodel/support/mongo_options.rb +9 -34
- data/lib/mongomodel/support/scope.rb +2 -14
- data/lib/mongomodel/version.rb +1 -1
- data/mongomodel.gemspec +3 -3
- data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +4 -6
- data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +123 -123
- data/spec/mongomodel/concerns/logging_spec.rb +1 -1
- data/spec/mongomodel/document/dynamic_finders_spec.rb +32 -32
- data/spec/mongomodel/support/scope_spec.rb +0 -18
- data/spec/spec.opts +0 -3
- data/spec/spec_helper.rb +4 -4
- data/spec/support/helpers/document_finder_stubs.rb +2 -2
- data/spec/support/matchers/be_a_subclass_of.rb +1 -1
- data/spec/support/matchers/be_truthy.rb +1 -1
- data/spec/support/matchers/find_with.rb +4 -4
- data/spec/support/matchers/respond_to_boolean.rb +1 -1
- data/spec/support/matchers/run_callbacks.rb +1 -1
- metadata +23 -74
@@ -6,8 +6,6 @@ module MongoModel
|
|
6
6
|
included do
|
7
7
|
undef_method :id if method_defined?(:id)
|
8
8
|
property :id, MongoModel::Reference, :as => '_id', :default => lambda { |doc| doc.generate_id }
|
9
|
-
|
10
|
-
class_inheritable_writer :collection_name
|
11
9
|
end
|
12
10
|
|
13
11
|
# Reload the document from the database. If the document
|
@@ -93,12 +91,16 @@ module MongoModel
|
|
93
91
|
|
94
92
|
def collection_name
|
95
93
|
if superclass.abstract_class?
|
96
|
-
|
94
|
+
@_collection_name || name.tableize.gsub(/\//, '.')
|
97
95
|
else
|
98
96
|
superclass.collection_name
|
99
97
|
end
|
100
98
|
end
|
101
99
|
|
100
|
+
def collection_name=(name)
|
101
|
+
@_collection_name = name
|
102
|
+
end
|
103
|
+
|
102
104
|
def use_type_selector?
|
103
105
|
!superclass.abstract_class?
|
104
106
|
end
|
@@ -116,11 +118,11 @@ module MongoModel
|
|
116
118
|
end
|
117
119
|
|
118
120
|
def save_safely?
|
119
|
-
@
|
121
|
+
@_save_safely
|
120
122
|
end
|
121
123
|
|
122
124
|
def save_safely=(val)
|
123
|
-
@
|
125
|
+
@_save_safely = val
|
124
126
|
end
|
125
127
|
end
|
126
128
|
|
@@ -23,10 +23,6 @@ module MongoModel
|
|
23
23
|
current_scope.clone
|
24
24
|
end
|
25
25
|
|
26
|
-
def scopes
|
27
|
-
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
|
28
|
-
end
|
29
|
-
|
30
26
|
def scope(name, scope)
|
31
27
|
name = name.to_sym
|
32
28
|
|
@@ -52,6 +48,28 @@ module MongoModel
|
|
52
48
|
previous_scope = default_scoping.last || unscoped
|
53
49
|
default_scoping << previous_scope.merge(scope)
|
54
50
|
end
|
51
|
+
|
52
|
+
def scopes
|
53
|
+
@_scopes ||= {}
|
54
|
+
end
|
55
|
+
|
56
|
+
def scopes=(scopes)
|
57
|
+
@_scopes = scopes
|
58
|
+
end
|
59
|
+
|
60
|
+
def default_scoping
|
61
|
+
@_default_scoping ||= []
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_scoping=(scoping)
|
65
|
+
@_default_scoping = scoping
|
66
|
+
end
|
67
|
+
|
68
|
+
def inherited(subclass)
|
69
|
+
super
|
70
|
+
subclass.scopes = scopes.dup
|
71
|
+
subclass.default_scoping = default_scoping.dup
|
72
|
+
end
|
55
73
|
|
56
74
|
protected
|
57
75
|
def with_scope(scope, &block)
|
@@ -76,10 +94,6 @@ module MongoModel
|
|
76
94
|
def reset_current_scopes
|
77
95
|
Thread.current[:"#{self}_scopes"] = nil
|
78
96
|
end
|
79
|
-
|
80
|
-
def default_scoping
|
81
|
-
read_inheritable_attribute(:default_scoping) || write_inheritable_attribute(:default_scoping, [])
|
82
|
-
end
|
83
97
|
end
|
84
98
|
end
|
85
99
|
end
|
data/lib/mongomodel/railtie.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module MongoModel
|
2
2
|
class Railtie < Rails::Railtie
|
3
|
-
|
4
|
-
config.generators.orm :mongo_model, :migration => false
|
3
|
+
config.app_generators.orm :mongo_model, :migration => false
|
5
4
|
|
6
5
|
rake_tasks do
|
7
6
|
load "mongomodel/tasks/database.rake"
|
@@ -18,7 +17,7 @@ module MongoModel
|
|
18
17
|
initializer "mongomodel.database_configuration" do |app|
|
19
18
|
require 'erb'
|
20
19
|
|
21
|
-
config =
|
20
|
+
config = Rails.root.join("config", "mongomodel.yml")
|
22
21
|
|
23
22
|
if File.exists?(config)
|
24
23
|
mongomodel_configuration = YAML::load(ERB.new(IO.read(config)).result)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute'
|
2
|
+
|
1
3
|
module MongoModel
|
2
4
|
class Collection < Array
|
3
5
|
module PropertyDefaults
|
@@ -14,7 +16,7 @@ module MongoModel
|
|
14
16
|
|
15
17
|
ARRAY_CONVERTER = Types.converter_for(Array)
|
16
18
|
|
17
|
-
|
19
|
+
class_attribute :type
|
18
20
|
self.type = Object
|
19
21
|
|
20
22
|
include DocumentParent
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute'
|
2
|
+
|
1
3
|
module MongoModel
|
2
4
|
class Map < Hash
|
3
5
|
module PropertyDefaults
|
@@ -12,10 +14,10 @@ module MongoModel
|
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
15
|
-
|
17
|
+
class_attribute :from
|
16
18
|
self.from = String
|
17
19
|
|
18
|
-
|
20
|
+
class_attribute :to
|
19
21
|
self.to = Object
|
20
22
|
|
21
23
|
HASH_CONVERTER = Types.converter_for(Hash)
|
@@ -26,31 +26,16 @@ module MongoModel
|
|
26
26
|
result = {}
|
27
27
|
|
28
28
|
(options[:conditions] || {}).each do |k, v|
|
29
|
-
|
30
|
-
key = k.field
|
31
|
-
else
|
32
|
-
key = k
|
33
|
-
end
|
29
|
+
key = k.is_a?(MongoOperator) ? k.field : k
|
34
30
|
|
35
31
|
if property = @model.properties[key]
|
36
32
|
key = property.as
|
37
|
-
|
38
|
-
if k.is_a?(MongoOperator)
|
39
|
-
value = k.to_mongo_selector(v.is_a?(Array) ? v.map { |i| property.to_query(i) } : property.to_query(v))
|
40
|
-
else
|
41
|
-
value = property.to_query(v)
|
42
|
-
end
|
33
|
+
value = v.is_a?(Array) ? v.map { |i| property.to_query(i) } : property.to_query(v);
|
43
34
|
else
|
44
|
-
|
45
|
-
|
46
|
-
if k.is_a?(MongoOperator)
|
47
|
-
value = k.to_mongo_selector(converter.to_mongo(v))
|
48
|
-
else
|
49
|
-
value = converter.to_mongo(v)
|
50
|
-
end
|
35
|
+
value = Types.converter_for(v.class).to_mongo(v)
|
51
36
|
end
|
52
|
-
|
53
|
-
result[key] = value
|
37
|
+
|
38
|
+
result[key] = k.is_a?(MongoOperator) ? k.to_mongo_selector(value) : value
|
54
39
|
end
|
55
40
|
|
56
41
|
result
|
@@ -59,7 +44,7 @@ module MongoModel
|
|
59
44
|
def extract_options(options)
|
60
45
|
result = {}
|
61
46
|
|
62
|
-
result[:fields] = options[:select] if options[:select]
|
47
|
+
result[:fields] = convert_select(options[:select]) if options[:select]
|
63
48
|
result[:skip] = options[:offset] if options[:offset]
|
64
49
|
result[:limit] = options[:limit] if options[:limit]
|
65
50
|
result[:sort] = MongoOrder.parse(options[:order]).to_sort(@model) if options[:order]
|
@@ -67,19 +52,9 @@ module MongoModel
|
|
67
52
|
result
|
68
53
|
end
|
69
54
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
order.map { |clause|
|
74
|
-
key, sort = clause.split(/ /)
|
75
|
-
|
76
|
-
property = @model.properties[key.to_sym]
|
77
|
-
sort = (sort =~ /desc/i) ? :descending : :ascending
|
78
|
-
|
79
|
-
[property ? property.as : key, sort]
|
80
|
-
} if order.size > 0
|
81
|
-
when String, Symbol
|
82
|
-
convert_order(order.to_s.split(/,/).map { |c| c.strip })
|
55
|
+
def convert_select(fields)
|
56
|
+
fields.map do |key|
|
57
|
+
(@model.properties[key.to_sym].try(:as) || key).to_sym
|
83
58
|
end
|
84
59
|
end
|
85
60
|
|
@@ -131,29 +131,17 @@ module MongoModel
|
|
131
131
|
end
|
132
132
|
|
133
133
|
def finder_options
|
134
|
-
@finder_options ||=
|
135
|
-
result = {}
|
136
|
-
|
134
|
+
@finder_options ||= {}.tap do |result|
|
137
135
|
result[:conditions] = finder_conditions if where_values.any?
|
138
136
|
result[:select] = select_values if select_values.any?
|
139
137
|
result[:order] = order_values if order_values.any?
|
140
138
|
result[:limit] = limit_value if limit_value.present?
|
141
139
|
result[:offset] = offset_value if offset_value.present?
|
142
|
-
|
143
|
-
result
|
144
140
|
end
|
145
141
|
end
|
146
142
|
|
147
143
|
def options_for_create
|
148
|
-
@options_for_create ||=
|
149
|
-
result = {}
|
150
|
-
|
151
|
-
finder_conditions.each do |k, v|
|
152
|
-
result[k] = v unless k.is_a?(MongoModel::MongoOperator)
|
153
|
-
end
|
154
|
-
|
155
|
-
result
|
156
|
-
end
|
144
|
+
@options_for_create ||= finder_conditions.reject { |k, v| k.is_a?(MongoModel::MongoOperator) }
|
157
145
|
end
|
158
146
|
|
159
147
|
def respond_to?(method, include_private = false)
|
data/lib/mongomodel/version.rb
CHANGED
data/mongomodel.gemspec
CHANGED
@@ -14,8 +14,8 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.required_rubygems_version = ">= 1.3.6"
|
15
15
|
s.rubyforge_project = "mongomodel"
|
16
16
|
|
17
|
-
s.add_dependency "activesupport", "~> 3.0
|
18
|
-
s.add_dependency "activemodel", "~> 3.0
|
17
|
+
s.add_dependency "activesupport", "~> 3.0"
|
18
|
+
s.add_dependency "activemodel", "~> 3.0"
|
19
19
|
s.add_dependency "mongo", "~> 1.3.0"
|
20
20
|
s.add_dependency "will_paginate", "~> 2.3.15"
|
21
21
|
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
end
|
25
25
|
|
26
26
|
s.add_development_dependency "bundler", ">= 1.0.0"
|
27
|
-
s.add_development_dependency "rspec", "
|
27
|
+
s.add_development_dependency "rspec", "~> 2.6.0"
|
28
28
|
|
29
29
|
s.files = `git ls-files`.split("\n")
|
30
30
|
s.require_path = 'lib'
|
@@ -8,8 +8,6 @@ module MongoModel
|
|
8
8
|
let(:user) { User.create! }
|
9
9
|
let(:special_user) { SpecialUser.create! }
|
10
10
|
|
11
|
-
subject { Article.new }
|
12
|
-
|
13
11
|
context "when uninitialized" do
|
14
12
|
it "should be nil" do
|
15
13
|
subject.user.should be_nil
|
@@ -79,6 +77,8 @@ module MongoModel
|
|
79
77
|
belongs_to :user
|
80
78
|
end
|
81
79
|
|
80
|
+
subject { Article.new }
|
81
|
+
|
82
82
|
it_should_behave_like "assigning correct class to belongs_to association"
|
83
83
|
|
84
84
|
describe "setting a different class type" do
|
@@ -92,8 +92,6 @@ module MongoModel
|
|
92
92
|
end
|
93
93
|
|
94
94
|
describe "#build_user" do
|
95
|
-
subject { Article.new }
|
96
|
-
|
97
95
|
let(:user) { subject.build_user(:id => '123') }
|
98
96
|
|
99
97
|
it "should return a new unsaved user with the given attributes" do
|
@@ -104,8 +102,6 @@ module MongoModel
|
|
104
102
|
end
|
105
103
|
|
106
104
|
describe "#create_user" do
|
107
|
-
subject { Article.new }
|
108
|
-
|
109
105
|
it "should return a new saved user with the given attributes" do
|
110
106
|
user = subject.create_user(:id => '123')
|
111
107
|
user.should be_an_instance_of(User)
|
@@ -120,6 +116,8 @@ module MongoModel
|
|
120
116
|
belongs_to :user, :polymorphic => true
|
121
117
|
end
|
122
118
|
|
119
|
+
subject { Article.new }
|
120
|
+
|
123
121
|
define_class(:NonUser, Document)
|
124
122
|
|
125
123
|
let(:non_user) { NonUser.create! }
|
@@ -13,6 +13,129 @@ module MongoModel
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
shared_examples_for "accessing and manipulating a has_many :by => :ids association" do
|
17
|
+
it "should access chapters" do
|
18
|
+
subject.chapters.should == [chapter1, chapter2]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should access chapter ids through association" do
|
22
|
+
subject.chapters.ids.should == [chapter1.id, chapter2.id]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have chapter ids" do
|
26
|
+
subject.chapter_ids.should == [chapter1.id, chapter2.id]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should add chapters with <<" do
|
30
|
+
subject.chapters << chapter3
|
31
|
+
subject.chapters.should == [chapter1, chapter2, chapter3]
|
32
|
+
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should add/change chapters with []=" do
|
36
|
+
subject.chapters[2] = chapter3
|
37
|
+
subject.chapters.should == [chapter1, chapter2, chapter3]
|
38
|
+
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should add chapters with concat" do
|
42
|
+
subject.chapters.concat([chapter3])
|
43
|
+
subject.chapters.should == [chapter1, chapter2, chapter3]
|
44
|
+
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should insert chapters" do
|
48
|
+
subject.chapters.insert(1, chapter3)
|
49
|
+
subject.chapters.should == [chapter1, chapter3, chapter2]
|
50
|
+
subject.chapter_ids.should == [chapter1.id, chapter3.id, chapter2.id]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should replace chapters" do
|
54
|
+
subject.chapters.replace([chapter2, chapter3])
|
55
|
+
subject.chapters.should == [chapter2, chapter3]
|
56
|
+
subject.chapter_ids.should == [chapter2.id, chapter3.id]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should add chapters with push" do
|
60
|
+
subject.chapters.push(chapter3)
|
61
|
+
subject.chapters.should == [chapter1, chapter2, chapter3]
|
62
|
+
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should add chapters with unshift" do
|
66
|
+
subject.chapters.unshift(chapter3)
|
67
|
+
subject.chapters.should == [chapter3, chapter1, chapter2]
|
68
|
+
subject.chapter_ids.should == [chapter3.id, chapter1.id, chapter2.id]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should clear chapters" do
|
72
|
+
subject.chapters.clear
|
73
|
+
subject.chapters.should be_empty
|
74
|
+
subject.chapter_ids.should be_empty
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should remove chapters with delete" do
|
78
|
+
subject.chapters.delete(chapter1)
|
79
|
+
subject.chapters.should == [chapter2]
|
80
|
+
subject.chapter_ids.should == [chapter2.id]
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should remove chapters with delete_at" do
|
84
|
+
subject.chapters.delete_at(0)
|
85
|
+
subject.chapters.should == [chapter2]
|
86
|
+
subject.chapter_ids.should == [chapter2.id]
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should remove chapters with delete_if" do
|
90
|
+
subject.chapters.delete_if { |c| c.id == chapter1.id }
|
91
|
+
subject.chapters.should == [chapter2]
|
92
|
+
subject.chapter_ids.should == [chapter2.id]
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should build a chapter" do
|
96
|
+
chapter4 = subject.chapters.build(:id => '4')
|
97
|
+
subject.chapters.should == [chapter1, chapter2, chapter4]
|
98
|
+
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
|
99
|
+
|
100
|
+
chapter4.should be_a_new_record
|
101
|
+
chapter4.id.should == '4'
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should create a chapter" do
|
105
|
+
chapter4 = subject.chapters.create(:id => '4')
|
106
|
+
subject.chapters.should == [chapter1, chapter2, chapter4]
|
107
|
+
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
|
108
|
+
|
109
|
+
chapter4.should_not be_a_new_record
|
110
|
+
chapter4.id.should == '4'
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should find chapters" do
|
114
|
+
# Create bogus chapters
|
115
|
+
Chapter.create!(:id => '999')
|
116
|
+
Chapter.create!(:id => '998')
|
117
|
+
|
118
|
+
result = subject.chapters.order(:id.desc)
|
119
|
+
result.should == [chapter2, chapter1]
|
120
|
+
end
|
121
|
+
|
122
|
+
describe "adding a non-chapter" do
|
123
|
+
def self.should_raise(message, &block)
|
124
|
+
it "should raise an AsssociationTypeMismatch error when #{message}" do
|
125
|
+
lambda { instance_eval(&block) }.should raise_error(AssociationTypeMismatch, "expected instance of Chapter but got NonChapter")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
should_raise("assigning an array containing non-chapters") { subject.chapters = [nonchapter] }
|
130
|
+
should_raise("adding a non-chapter using <<") { subject.chapters << nonchapter }
|
131
|
+
should_raise("adding non-chapters with concat") { subject.chapters.concat([nonchapter]) }
|
132
|
+
should_raise("inserting chapters") { subject.chapters.insert(1, nonchapter) }
|
133
|
+
should_raise("replacing chapters") { subject.chapters.replace([nonchapter]) }
|
134
|
+
should_raise("addding chapters with push") { subject.chapters.push(nonchapter) }
|
135
|
+
should_raise("addding chapters with unshift") { subject.chapters.unshift(nonchapter) }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
16
139
|
specs_for(Document, EmbeddedDocument) do
|
17
140
|
describe "has_many :by => :ids association" do
|
18
141
|
define_class(:Chapter, Document)
|
@@ -39,129 +162,6 @@ module MongoModel
|
|
39
162
|
end
|
40
163
|
end
|
41
164
|
|
42
|
-
shared_examples_for "accessing and manipulating a has_many :by => :ids association" do
|
43
|
-
it "should access chapters" do
|
44
|
-
subject.chapters.should == [chapter1, chapter2]
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should access chapter ids through association" do
|
48
|
-
subject.chapters.ids.should == [chapter1.id, chapter2.id]
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should have chapter ids" do
|
52
|
-
subject.chapter_ids.should == [chapter1.id, chapter2.id]
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should add chapters with <<" do
|
56
|
-
subject.chapters << chapter3
|
57
|
-
subject.chapters.should == [chapter1, chapter2, chapter3]
|
58
|
-
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should add/change chapters with []=" do
|
62
|
-
subject.chapters[2] = chapter3
|
63
|
-
subject.chapters.should == [chapter1, chapter2, chapter3]
|
64
|
-
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should add chapters with concat" do
|
68
|
-
subject.chapters.concat([chapter3])
|
69
|
-
subject.chapters.should == [chapter1, chapter2, chapter3]
|
70
|
-
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should insert chapters" do
|
74
|
-
subject.chapters.insert(1, chapter3)
|
75
|
-
subject.chapters.should == [chapter1, chapter3, chapter2]
|
76
|
-
subject.chapter_ids.should == [chapter1.id, chapter3.id, chapter2.id]
|
77
|
-
end
|
78
|
-
|
79
|
-
it "should replace chapters" do
|
80
|
-
subject.chapters.replace([chapter2, chapter3])
|
81
|
-
subject.chapters.should == [chapter2, chapter3]
|
82
|
-
subject.chapter_ids.should == [chapter2.id, chapter3.id]
|
83
|
-
end
|
84
|
-
|
85
|
-
it "should add chapters with push" do
|
86
|
-
subject.chapters.push(chapter3)
|
87
|
-
subject.chapters.should == [chapter1, chapter2, chapter3]
|
88
|
-
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should add chapters with unshift" do
|
92
|
-
subject.chapters.unshift(chapter3)
|
93
|
-
subject.chapters.should == [chapter3, chapter1, chapter2]
|
94
|
-
subject.chapter_ids.should == [chapter3.id, chapter1.id, chapter2.id]
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should clear chapters" do
|
98
|
-
subject.chapters.clear
|
99
|
-
subject.chapters.should be_empty
|
100
|
-
subject.chapter_ids.should be_empty
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should remove chapters with delete" do
|
104
|
-
subject.chapters.delete(chapter1)
|
105
|
-
subject.chapters.should == [chapter2]
|
106
|
-
subject.chapter_ids.should == [chapter2.id]
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should remove chapters with delete_at" do
|
110
|
-
subject.chapters.delete_at(0)
|
111
|
-
subject.chapters.should == [chapter2]
|
112
|
-
subject.chapter_ids.should == [chapter2.id]
|
113
|
-
end
|
114
|
-
|
115
|
-
it "should remove chapters with delete_if" do
|
116
|
-
subject.chapters.delete_if { |c| c.id == chapter1.id }
|
117
|
-
subject.chapters.should == [chapter2]
|
118
|
-
subject.chapter_ids.should == [chapter2.id]
|
119
|
-
end
|
120
|
-
|
121
|
-
it "should build a chapter" do
|
122
|
-
chapter4 = subject.chapters.build(:id => '4')
|
123
|
-
subject.chapters.should == [chapter1, chapter2, chapter4]
|
124
|
-
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
|
125
|
-
|
126
|
-
chapter4.should be_a_new_record
|
127
|
-
chapter4.id.should == '4'
|
128
|
-
end
|
129
|
-
|
130
|
-
it "should create a chapter" do
|
131
|
-
chapter4 = subject.chapters.create(:id => '4')
|
132
|
-
subject.chapters.should == [chapter1, chapter2, chapter4]
|
133
|
-
subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
|
134
|
-
|
135
|
-
chapter4.should_not be_a_new_record
|
136
|
-
chapter4.id.should == '4'
|
137
|
-
end
|
138
|
-
|
139
|
-
it "should find chapters" do
|
140
|
-
# Create bogus chapters
|
141
|
-
Chapter.create!(:id => '999')
|
142
|
-
Chapter.create!(:id => '998')
|
143
|
-
|
144
|
-
result = subject.chapters.order(:id.desc)
|
145
|
-
result.should == [chapter2, chapter1]
|
146
|
-
end
|
147
|
-
|
148
|
-
describe "adding a non-chapter" do
|
149
|
-
def self.should_raise(message, &block)
|
150
|
-
it "should raise an AsssociationTypeMismatch error when #{message}" do
|
151
|
-
lambda { instance_eval(&block) }.should raise_error(AssociationTypeMismatch, "expected instance of Chapter but got NonChapter")
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
should_raise("assigning an array containing non-chapters") { subject.chapters = [nonchapter] }
|
156
|
-
should_raise("adding a non-chapter using <<") { subject.chapters << nonchapter }
|
157
|
-
should_raise("adding non-chapters with concat") { subject.chapters.concat([nonchapter]) }
|
158
|
-
should_raise("inserting chapters") { subject.chapters.insert(1, nonchapter) }
|
159
|
-
should_raise("replacing chapters") { subject.chapters.replace([nonchapter]) }
|
160
|
-
should_raise("addding chapters with push") { subject.chapters.push(nonchapter) }
|
161
|
-
should_raise("addding chapters with unshift") { subject.chapters.unshift(nonchapter) }
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
165
|
context "with chapters set" do
|
166
166
|
subject { Book.new(:chapters => [chapter1, chapter2]) }
|
167
167
|
it_should_behave_like "accessing and manipulating a has_many :by => :ids association"
|