active-fedora 9.0.6 → 9.0.8
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.
- checksums.yaml +5 -5
- data/History.txt +57 -0
- data/lib/active_fedora.rb +5 -0
- data/lib/active_fedora/associations/collection_association.rb +1 -18
- data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +12 -10
- data/lib/active_fedora/core.rb +15 -17
- data/lib/active_fedora/core/fedora_id_translator.rb +12 -0
- data/lib/active_fedora/core/fedora_uri_translator.rb +9 -0
- data/lib/active_fedora/errors.rb +4 -0
- data/lib/active_fedora/fedora_attributes.rb +15 -5
- data/lib/active_fedora/file.rb +2 -0
- data/lib/active_fedora/inheritable_accessors.rb +26 -0
- data/lib/active_fedora/reflection.rb +3 -1
- data/lib/active_fedora/relation/finder_methods.rb +27 -3
- data/lib/active_fedora/version.rb +1 -1
- data/lib/active_fedora/versions_graph.rb +7 -8
- data/spec/integration/associations_spec.rb +34 -22
- data/spec/integration/belongs_to_association_spec.rb +118 -47
- data/spec/integration/collection_association_spec.rb +46 -0
- data/spec/integration/has_and_belongs_to_many_associations_spec.rb +178 -139
- data/spec/integration/versionable_spec.rb +38 -1
- data/spec/samples/samples.rb +0 -1
- data/spec/unit/base_spec.rb +51 -0
- data/spec/unit/core/fedora_id_translator_spec.rb +20 -0
- data/spec/unit/core/fedora_uri_translator_spec.rb +19 -0
- data/spec/unit/core_spec.rb +50 -0
- data/spec/unit/has_many_association_spec.rb +27 -2
- data/spec/unit/qualified_dublin_core_datastream_spec.rb +0 -6
- data/spec/unit/reflection_spec.rb +44 -0
- metadata +9 -13
- data/spec/samples/marpa-dc_datastream.rb +0 -102
- data/spec/samples/models/audio_record.rb +0 -29
- data/spec/samples/models/image.rb +0 -5
- data/spec/samples/models/oral_history.rb +0 -36
- data/spec/samples/models/seminar.rb +0 -29
- data/spec/samples/models/seminar_audio_file.rb +0 -32
- data/spec/samples/oral_history_sample_model.rb +0 -30
- data/spec/samples/special_thing.rb +0 -44
@@ -10,6 +10,9 @@ describe ActiveFedora::Base do
|
|
10
10
|
belongs_to :library, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasConstituent
|
11
11
|
end
|
12
12
|
class SpecialInheritedBook < Book
|
13
|
+
def assert_content_model
|
14
|
+
self.has_model = [self.class.to_s, self.class.superclass.to_s]
|
15
|
+
end
|
13
16
|
end
|
14
17
|
|
15
18
|
end
|
@@ -73,8 +76,8 @@ describe ActiveFedora::Base do
|
|
73
76
|
end
|
74
77
|
|
75
78
|
it "should cast to the most specific class for the association" do
|
76
|
-
@library2.books[0].
|
77
|
-
@library2.books[1].
|
79
|
+
expect(@library2.books[0]).to be_instance_of Book
|
80
|
+
expect(@library2.books[1]).to be_instance_of SpecialInheritedBook
|
78
81
|
end
|
79
82
|
|
80
83
|
after do
|
@@ -90,104 +93,172 @@ describe ActiveFedora::Base do
|
|
90
93
|
belongs_to :complex_collection, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ComplexCollection'
|
91
94
|
end
|
92
95
|
|
93
|
-
|
96
|
+
#NOTE: As RDF assertions seem to be returned in alphabetical order, the "Z" is to insure this is stored
|
97
|
+
# after the SimpleObject relationship for this particular case. This is to ensure people don't just change ActiveFedora
|
98
|
+
# to pick the first content model and it works by alphabetical chance.
|
99
|
+
class ZComplexObject < SimpleObject
|
94
100
|
belongs_to :simple_collection, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SimpleCollection'
|
95
101
|
belongs_to :complex_collection, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ComplexCollection'
|
102
|
+
|
103
|
+
def assert_content_model
|
104
|
+
self.has_model = [self.class.to_s, self.class.superclass.to_s]
|
105
|
+
end
|
96
106
|
end
|
97
107
|
|
98
108
|
class SimpleCollection < ActiveFedora::Base
|
99
109
|
has_many :objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SimpleObject', autosave: true
|
100
|
-
has_many :complex_objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: '
|
110
|
+
has_many :complex_objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ZComplexObject', autosave: true
|
101
111
|
end
|
102
112
|
|
103
113
|
class ComplexCollection < SimpleCollection
|
104
114
|
has_many :objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SimpleObject', autosave: true
|
105
|
-
has_many :complex_objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: '
|
115
|
+
has_many :complex_objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'ZComplexObject', autosave: true
|
116
|
+
|
117
|
+
def assert_content_model
|
118
|
+
self.has_model = [self.class.to_s, self.class.superclass.to_s]
|
119
|
+
end
|
106
120
|
end
|
107
121
|
|
108
122
|
end
|
109
123
|
after :all do
|
110
124
|
Object.send(:remove_const, :SimpleObject)
|
111
|
-
Object.send(:remove_const, :
|
125
|
+
Object.send(:remove_const, :ZComplexObject)
|
112
126
|
Object.send(:remove_const, :SimpleCollection)
|
113
127
|
Object.send(:remove_const, :ComplexCollection)
|
114
128
|
end
|
115
129
|
|
116
130
|
describe "saving between the before and after hooks" do
|
131
|
+
let(:complex_object) { ZComplexObject.find(ZComplexObject.create.id) }
|
132
|
+
let(:complex_collection) { ComplexCollection.find(ComplexCollection.create.id) }
|
133
|
+
|
134
|
+
context "Verify that an inherited object will save and retrieve with the correct models" do
|
135
|
+
it "should have added the inverse relationship for the correct class" do
|
136
|
+
expect(complex_object.has_model).to match_array(["SimpleObject", "ZComplexObject"])
|
137
|
+
expect(complex_collection.has_model).to match_array(["SimpleCollection", "ComplexCollection"])
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
117
141
|
context "Add a complex_object into a simple_collection" do
|
142
|
+
let(:simple_collection) { SimpleCollection.create }
|
143
|
+
|
118
144
|
before do
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
@simple_collection.objects = [@complex_object]
|
123
|
-
@simple_collection.save!
|
124
|
-
@complex_collection.save!
|
145
|
+
simple_collection.objects = [complex_object]
|
146
|
+
simple_collection.save!
|
147
|
+
complex_collection.save!
|
125
148
|
end
|
126
149
|
it "should have added the inverse relationship for the correct class" do
|
127
|
-
expect(
|
128
|
-
expect(
|
150
|
+
expect(complex_object.simple_collection).to be_instance_of SimpleCollection
|
151
|
+
expect(complex_object.complex_collection).to be_nil
|
129
152
|
end
|
130
153
|
end
|
131
154
|
|
132
155
|
context "Add a complex_object into a complex_collection" do
|
133
156
|
before do
|
134
|
-
|
135
|
-
|
136
|
-
@complex_collection.objects = [@complex_object] # this sticks it into the :objects association, but since it is a ComplexObject it should also be fetched by :complex_collection association
|
137
|
-
@complex_collection.save
|
157
|
+
complex_collection.objects = [complex_object] # this sticks it into the :objects association, but since it is a ZComplexObject it should also be fetched by :complex_collection association
|
158
|
+
complex_collection.save
|
138
159
|
end
|
139
160
|
|
140
161
|
it "should have added the inverse relationship for the correct class" do
|
141
|
-
expect(
|
142
|
-
expect(
|
162
|
+
expect(complex_object.complex_collection).to be_instance_of ComplexCollection
|
163
|
+
expect(complex_object.reload.simple_collection).to be_instance_of ComplexCollection
|
143
164
|
end
|
144
165
|
end
|
145
166
|
|
146
167
|
context "Adding mixed types on a base class with a filtered has_many relationship" do
|
168
|
+
let(:simple_collection) { SimpleCollection.create }
|
169
|
+
let(:simple_object) { SimpleObject.create }
|
170
|
+
|
147
171
|
before do
|
148
|
-
|
149
|
-
|
150
|
-
@simple_object = SimpleObject.create
|
151
|
-
@simple_collection.objects = [@complex_object, @simple_object]
|
152
|
-
@simple_collection.save!
|
172
|
+
simple_collection.objects = [complex_object, simple_object]
|
173
|
+
simple_collection.save!
|
153
174
|
end
|
154
175
|
it "ignores objects who's classes aren't specified" do
|
155
|
-
expect(
|
156
|
-
expect(
|
157
|
-
expect(
|
176
|
+
expect(simple_collection.complex_objects.size).to eq 1
|
177
|
+
expect(simple_collection.complex_objects[0]).to be_instance_of ZComplexObject
|
178
|
+
expect(simple_collection.complex_objects[1]).to be_nil
|
158
179
|
|
159
|
-
expect(
|
160
|
-
expect(
|
161
|
-
expect(
|
180
|
+
expect(simple_collection.objects.size).to eq 2
|
181
|
+
expect(simple_collection.objects[0]).to be_instance_of ZComplexObject
|
182
|
+
expect(simple_collection.objects[1]).to be_instance_of SimpleObject
|
162
183
|
|
163
|
-
expect(
|
164
|
-
expect(
|
184
|
+
expect(simple_object.simple_collection).to be_instance_of SimpleCollection
|
185
|
+
expect(simple_object.complex_collection).to be_nil
|
165
186
|
end
|
166
187
|
end
|
167
188
|
|
168
189
|
context "Adding mixed types on a subclass with a filtered has_many relationship" do
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
@complex_collection.save!
|
190
|
+
let(:simple_object) { SimpleObject.create }
|
191
|
+
|
192
|
+
before do
|
193
|
+
complex_collection.objects = [complex_object, simple_object]
|
194
|
+
complex_collection.save!
|
175
195
|
end
|
176
196
|
it "ignores objects who's classes aren't specified" do
|
177
|
-
expect(
|
178
|
-
expect(
|
179
|
-
expect(
|
197
|
+
expect(complex_collection.complex_objects.size).to eq 1
|
198
|
+
expect(complex_collection.complex_objects[0]).to be_instance_of ZComplexObject
|
199
|
+
expect(complex_collection.complex_objects[1]).to be_nil
|
180
200
|
|
181
|
-
expect(
|
182
|
-
expect(
|
183
|
-
expect(
|
201
|
+
expect(complex_collection.objects.size).to eq 2
|
202
|
+
expect(complex_collection.objects[0]).to be_instance_of ZComplexObject
|
203
|
+
expect(complex_collection.objects[1]).to be_instance_of SimpleObject
|
184
204
|
|
185
|
-
expect(
|
186
|
-
expect(
|
205
|
+
expect(simple_object.complex_collection).to be_instance_of ComplexCollection
|
206
|
+
expect(simple_object.reload.simple_collection).to be_instance_of ComplexCollection
|
187
207
|
end
|
188
208
|
end
|
189
209
|
end
|
190
210
|
end
|
211
|
+
|
212
|
+
describe "casting inheritance super class test cases" do
|
213
|
+
before :all do
|
214
|
+
class SuperclassObject < ActiveFedora::Base
|
215
|
+
belongs_to :superclass_collection, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SuperclassCollection'
|
216
|
+
|
217
|
+
def assert_content_model
|
218
|
+
self.has_model = [self.class.to_s, self.class.superclass.to_s]
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
class SubclassObject < SuperclassObject
|
223
|
+
end
|
224
|
+
|
225
|
+
class SuperclassCollection < ActiveFedora::Base
|
226
|
+
has_many :objects, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, class_name: 'SuperclassObject', autosave: true
|
227
|
+
end
|
228
|
+
end
|
229
|
+
after :all do
|
230
|
+
Object.send(:remove_const, :SuperclassObject)
|
231
|
+
Object.send(:remove_const, :SubclassObject)
|
232
|
+
Object.send(:remove_const, :SuperclassCollection)
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "Adding subclass objects" do
|
236
|
+
let(:superclass_collection) { SuperclassCollection.create }
|
237
|
+
let(:superclass_object) { SubclassObject.create }
|
238
|
+
|
239
|
+
context "Add a subclass_object into a superclass_collection" do
|
240
|
+
before do
|
241
|
+
superclass_collection.objects = [subclass_object]
|
242
|
+
superclass_collection.save!
|
243
|
+
end
|
244
|
+
it "should have added the inverse relationship for the correct class" do
|
245
|
+
expect(subclass_object.superclass_collection).to be_instance_of SuperclassCollection
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context "Set the superclass_collection of a subclass object"
|
250
|
+
let(:subclass_object) { SubclassObject.create }
|
251
|
+
|
252
|
+
before do
|
253
|
+
subclass_object.superclass_collection = superclass_collection
|
254
|
+
subclass_object.save!
|
255
|
+
end
|
256
|
+
it "should have added the inverse relationship for the correct class" do
|
257
|
+
expect(superclass_collection.objects.size).to eq 1
|
258
|
+
expect(superclass_collection.objects[0]).to be_instance_of SubclassObject
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
191
262
|
end
|
192
263
|
|
193
264
|
|
@@ -71,4 +71,50 @@ describe ActiveFedora::Base do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
describe "finding the inverse" do
|
75
|
+
context "when no inverse exists" do
|
76
|
+
before do
|
77
|
+
class Item < ActiveFedora::Base
|
78
|
+
end
|
79
|
+
class Container < ActiveFedora::Base
|
80
|
+
has_many :items
|
81
|
+
end
|
82
|
+
end
|
83
|
+
after do
|
84
|
+
Object.send(:remove_const, :Item)
|
85
|
+
Object.send(:remove_const, :Container)
|
86
|
+
end
|
87
|
+
|
88
|
+
let(:instance) { Container.new }
|
89
|
+
subject { instance.items }
|
90
|
+
|
91
|
+
it "raises an error" do
|
92
|
+
expect { subject }.to raise_error "No :inverse_of or :predicate attribute was set or could be inferred for has_many :items on Container"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when classes are namespaced" do
|
97
|
+
before do
|
98
|
+
class Item < ActiveFedora::Base
|
99
|
+
has_and_belongs_to_many :container, predicate: ::RDF::DC.extent, class_name: 'Foo::Container'
|
100
|
+
end
|
101
|
+
module Foo
|
102
|
+
class Container < ActiveFedora::Base
|
103
|
+
has_many :items
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
after do
|
108
|
+
Object.send(:remove_const, :Item)
|
109
|
+
Object.send(:remove_const, :Foo)
|
110
|
+
end
|
111
|
+
|
112
|
+
let(:instance) { Foo::Container.new }
|
113
|
+
subject { instance.items }
|
114
|
+
|
115
|
+
it "finds the association" do
|
116
|
+
expect(subject).to eq []
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
74
120
|
end
|
@@ -2,109 +2,131 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ActiveFedora::Base do
|
4
4
|
describe "with inverse" do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
context "that is also a HABTM" do
|
6
|
+
before do
|
7
|
+
class Book < ActiveFedora::Base
|
8
|
+
has_and_belongs_to_many :topics, predicate: ::RDF::FOAF.primaryTopic, inverse_of: :books
|
9
|
+
end
|
10
|
+
|
11
|
+
class Topic < ActiveFedora::Base
|
12
|
+
has_and_belongs_to_many :books, predicate: ::RDF::FOAF.isPrimaryTopicOf
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
|
-
|
16
|
+
after do
|
17
|
+
Object.send(:remove_const, :Book)
|
18
|
+
Object.send(:remove_const, :Topic)
|
12
19
|
end
|
13
20
|
|
21
|
+
describe "an unsaved instance" do
|
22
|
+
let(:topic1) { Topic.create }
|
23
|
+
let(:book) { Book.create }
|
14
24
|
|
15
|
-
|
16
|
-
|
25
|
+
it "habtm should set and remove relationships bidirectionally" do
|
26
|
+
book.topics << topic1
|
27
|
+
expect(book.topics).to eq [topic1]
|
28
|
+
expect(topic1.books).to eq [book]
|
29
|
+
expect(topic1.reload.books).to eq [book]
|
17
30
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
31
|
+
book.topics.delete(topic1)
|
32
|
+
expect(book.topics).to be_empty
|
33
|
+
expect(topic1.books).to be_empty
|
34
|
+
end
|
22
35
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
36
|
+
it "Should allow for more than 10 items" do
|
37
|
+
(1..12).each do
|
38
|
+
book.topics << Topic.create
|
39
|
+
end
|
40
|
+
book.save
|
41
|
+
expect(book.topics.count).to eq 12
|
42
|
+
book2 = Book.find(book.id)
|
43
|
+
expect(book2.topics.count).to eq 12
|
44
|
+
end
|
29
45
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
46
|
+
context "with subclassed objects" do
|
47
|
+
before do
|
48
|
+
class SpecialInheritedBook < Book
|
49
|
+
end
|
50
|
+
end
|
35
51
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
expect(topic1.books).to eq [@book]
|
40
|
-
expect(topic1.reload.books).to eq [@book]
|
52
|
+
after do
|
53
|
+
Object.send(:remove_const, :SpecialInheritedBook)
|
54
|
+
end
|
41
55
|
|
42
|
-
|
43
|
-
|
44
|
-
|
56
|
+
let!(:special_book) { SpecialInheritedBook.create }
|
57
|
+
it "Should find inherited objects along with base objects" do
|
58
|
+
book.topics << topic1
|
59
|
+
special_book.topics << topic1
|
60
|
+
expect(topic1.books).to match_array [book, special_book]
|
61
|
+
expect(topic1.reload.books).to match_array [book, special_book]
|
62
|
+
end
|
63
|
+
end
|
45
64
|
end
|
46
65
|
|
47
|
-
|
48
|
-
(
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
let!(:special_book) { SpecialInheritedBook.create }
|
59
|
-
it "Should find inherited objects along with base objects" do
|
60
|
-
@book.topics << topic1
|
61
|
-
special_book.topics << topic1
|
62
|
-
expect(topic1.books).to eq [@book, special_book]
|
63
|
-
expect(topic1.reload.books).to eq [@book, special_book]
|
66
|
+
describe "a saved instance" do
|
67
|
+
let!(:book) { Book.create }
|
68
|
+
let!(:topic1) { Topic.create }
|
69
|
+
let!(:topic2) { Topic.create }
|
70
|
+
|
71
|
+
it "should set relationships bidirectionally" do
|
72
|
+
book.topics << topic1
|
73
|
+
expect(book.topics).to eq [topic1]
|
74
|
+
expect(book['topic_ids']).to eq [topic1.id]
|
75
|
+
expect(topic1['book_ids']).to eq [book.id]
|
76
|
+
expect(Topic.find(topic1.id).books).to eq [book] #Can't have saved it because book isn't saved yet.
|
64
77
|
end
|
65
|
-
end
|
66
78
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
79
|
+
it "should save new child objects" do
|
80
|
+
book.topics << Topic.new
|
81
|
+
expect(book.topics.first.id).to_not be_nil
|
82
|
+
end
|
71
83
|
|
72
|
-
|
84
|
+
it "should clear out the old associtions" do
|
85
|
+
book.topics = [topic1]
|
86
|
+
book.topics = [topic2]
|
87
|
+
expect(book.topic_ids).to eq [topic2.id]
|
88
|
+
end
|
73
89
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
90
|
+
context "with members" do
|
91
|
+
before do
|
92
|
+
book.topics = [topic1, topic2]
|
93
|
+
book.save
|
94
|
+
end
|
78
95
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
96
|
+
context "destroy" do
|
97
|
+
it "should remove the associations" do
|
98
|
+
book.destroy
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
85
102
|
end
|
103
|
+
end
|
86
104
|
|
87
|
-
|
88
|
-
|
89
|
-
|
105
|
+
context "that is a has_many" do
|
106
|
+
before do
|
107
|
+
class Book < ActiveFedora::Base
|
108
|
+
has_many :collections
|
109
|
+
end
|
110
|
+
|
111
|
+
class Collection < ActiveFedora::Base
|
112
|
+
has_and_belongs_to_many :books, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
|
113
|
+
end
|
90
114
|
end
|
91
115
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
expect(book.topic_ids).to eq [topic2.id]
|
116
|
+
after do
|
117
|
+
Object.send(:remove_const, :Book)
|
118
|
+
Object.send(:remove_const, :Collection)
|
96
119
|
end
|
97
120
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
book.save
|
102
|
-
end
|
121
|
+
describe "add and remove members" do
|
122
|
+
let(:collection) { Collection.create }
|
123
|
+
let(:book) { Book.create }
|
103
124
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
125
|
+
it "is successful" do
|
126
|
+
collection.books << book
|
127
|
+
expect {
|
128
|
+
collection.books.delete(book)
|
129
|
+
}.to change { collection.books.size }.from(1).to(0)
|
108
130
|
end
|
109
131
|
end
|
110
132
|
end
|
@@ -297,87 +319,104 @@ describe ActiveFedora::Base do
|
|
297
319
|
end
|
298
320
|
end
|
299
321
|
end
|
300
|
-
end
|
301
322
|
|
302
|
-
describe "create" do
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
323
|
+
describe "create" do
|
324
|
+
before do
|
325
|
+
class Book < ActiveFedora::Base
|
326
|
+
has_and_belongs_to_many :collections, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isMemberOfCollection
|
327
|
+
end
|
307
328
|
|
308
|
-
|
309
|
-
|
329
|
+
class Collection < ActiveFedora::Base
|
330
|
+
property :title, predicate: ::RDF::DC.title
|
331
|
+
end
|
310
332
|
end
|
311
|
-
end
|
312
333
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
334
|
+
after do
|
335
|
+
Object.send(:remove_const, :Book)
|
336
|
+
Object.send(:remove_const, :Collection)
|
337
|
+
end
|
317
338
|
|
318
|
-
|
339
|
+
let(:book) { Book.create }
|
319
340
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
341
|
+
it "should create" do
|
342
|
+
collection = book.collections.create(title: ["Permanent"])
|
343
|
+
expect(collection).to be_kind_of Collection
|
344
|
+
expect(book.collections).to include collection
|
345
|
+
book.save
|
346
|
+
expect(book.reload.collections.first.title).to eq ['Permanent']
|
347
|
+
end
|
326
348
|
end
|
327
|
-
end
|
328
349
|
|
329
350
|
|
330
|
-
describe "Autosave" do
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
351
|
+
describe "Autosave" do
|
352
|
+
before do
|
353
|
+
class Item < ActiveFedora::Base
|
354
|
+
has_many :components
|
355
|
+
has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
|
356
|
+
m.field "title", :string
|
357
|
+
end
|
358
|
+
has_attributes :title, datastream: 'foo'
|
359
|
+
end
|
360
|
+
|
361
|
+
class Component < ActiveFedora::Base
|
362
|
+
has_and_belongs_to_many :items, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
|
363
|
+
has_metadata "foo", type: ActiveFedora::SimpleDatastream do |m|
|
364
|
+
m.field "description", :string
|
365
|
+
end
|
366
|
+
has_attributes :description, datastream: 'foo'
|
336
367
|
end
|
337
|
-
has_attributes :title, datastream: 'foo'
|
338
|
-
end
|
339
368
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
m.field "description", :string
|
369
|
+
after do
|
370
|
+
Object.send(:remove_const, :Item)
|
371
|
+
Object.send(:remove_const, :Component)
|
344
372
|
end
|
345
|
-
has_attributes :description, datastream: 'foo'
|
346
|
-
end
|
347
|
-
end
|
348
373
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
374
|
+
describe "From the has_and_belongs_to_many side" do
|
375
|
+
describe "dependent records" do
|
376
|
+
let(:component) { Component.create(items: [Item.new(title: 'my title')]) }
|
377
|
+
|
378
|
+
it "should be saved" do
|
379
|
+
component.reload
|
380
|
+
expect(component.items.first.title).to eq 'my title'
|
381
|
+
end
|
382
|
+
end
|
353
383
|
|
354
|
-
|
355
|
-
|
356
|
-
|
384
|
+
describe "shifting" do
|
385
|
+
let(:component) { Component.new }
|
386
|
+
let(:item) { Item.create }
|
357
387
|
|
358
|
-
|
359
|
-
|
360
|
-
|
388
|
+
it "should set item_ids" do
|
389
|
+
component.items << item
|
390
|
+
expect(component.item_ids).to eq [item.id]
|
391
|
+
end
|
392
|
+
end
|
361
393
|
end
|
362
|
-
end
|
363
394
|
|
364
|
-
|
365
|
-
|
366
|
-
|
395
|
+
context "when the has_and_belongs_to_many provides an inverse_of" do
|
396
|
+
let(:reflection) { Component.reflect_on_association(:items) }
|
397
|
+
before do
|
398
|
+
reflection.options[:inverse_of] = :components
|
399
|
+
end
|
400
|
+
|
401
|
+
describe "shifting" do
|
402
|
+
let(:component) { Component.create }
|
403
|
+
let(:item) { Item.new }
|
367
404
|
|
368
|
-
|
369
|
-
|
370
|
-
|
405
|
+
it "should set item_ids" do
|
406
|
+
component.items << item
|
407
|
+
expect(component.item_ids).to eq [item.id]
|
408
|
+
end
|
409
|
+
end
|
371
410
|
end
|
372
|
-
end
|
373
|
-
end
|
374
411
|
|
375
|
-
|
376
|
-
|
412
|
+
describe "From the has_many side" do
|
413
|
+
let(:item) { Item.create(components: [Component.new(description: 'my description')]) }
|
377
414
|
|
378
|
-
|
379
|
-
|
380
|
-
|
415
|
+
it "should save dependent records" do
|
416
|
+
item.reload
|
417
|
+
expect(item.components.first.description).to eq 'my description'
|
418
|
+
end
|
419
|
+
end
|
381
420
|
end
|
382
421
|
end
|
383
422
|
end
|