active-fedora 9.0.2 → 9.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/History.txt +85 -0
- data/README.md +2 -4
- data/active-fedora.gemspec +1 -0
- data/lib/active_fedora.rb +5 -0
- data/lib/active_fedora/associations/builder/has_many.rb +1 -1
- data/lib/active_fedora/associations/collection_association.rb +1 -18
- data/lib/active_fedora/associations/contains_association.rb +3 -1
- data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +12 -10
- data/lib/active_fedora/attached_files.rb +6 -3
- data/lib/active_fedora/change_set.rb +2 -2
- data/lib/active_fedora/core.rb +26 -38
- 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 +25 -1
- data/lib/active_fedora/file.rb +2 -15
- data/lib/active_fedora/inheritable_accessors.rb +26 -0
- data/lib/active_fedora/nom_datastream.rb +6 -4
- data/lib/active_fedora/rdf/ntriples_rdf_datastream.rb +0 -4
- data/lib/active_fedora/reflection.rb +3 -1
- data/lib/active_fedora/relation/finder_methods.rb +36 -5
- data/lib/active_fedora/version.rb +1 -1
- data/lib/active_fedora/versions_graph.rb +7 -8
- data/spec/integration/associations_spec.rb +64 -21
- 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/query_result_builder_spec.rb +2 -2
- data/spec/integration/versionable_spec.rb +38 -1
- data/spec/samples/samples.rb +0 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/base_spec.rb +98 -0
- data/spec/unit/change_set_spec.rb +4 -2
- 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
- data/spec/unit/simple_datastream_spec.rb +32 -0
- metadata +23 -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
data/lib/active_fedora/file.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'deprecation'
|
2
|
+
|
1
3
|
module ActiveFedora
|
2
4
|
|
3
5
|
#This class represents a Fedora datastream
|
@@ -156,21 +158,6 @@ module ActiveFedora
|
|
156
158
|
super || content_changed?
|
157
159
|
end
|
158
160
|
|
159
|
-
|
160
|
-
class << self
|
161
|
-
def default_attributes
|
162
|
-
{}
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def default_attributes
|
167
|
-
@default_attributes ||= self.class.default_attributes
|
168
|
-
end
|
169
|
-
|
170
|
-
def default_attributes= attributes
|
171
|
-
@default_attributes = default_attributes.merge attributes
|
172
|
-
end
|
173
|
-
|
174
161
|
def original_name= name
|
175
162
|
@original_name = name
|
176
163
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Similar to ActiveSupport.class_attribute but with a setter that doesn't use the #{name}= syntax
|
2
|
+
# This preserves backward compatibility with the API in ActiveTriples
|
3
|
+
|
4
|
+
module ActiveFedora
|
5
|
+
module InheritableAccessors
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
module ClassMethods
|
8
|
+
def define_inheritable_accessor(*names)
|
9
|
+
names.each do |name|
|
10
|
+
define_accessor(name, nil)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def define_accessor(name, val)
|
16
|
+
singleton_class.class_eval do
|
17
|
+
remove_possible_method(name)
|
18
|
+
define_method(name) do |uri = nil|
|
19
|
+
define_accessor(name, uri) if uri
|
20
|
+
val
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -18,10 +18,6 @@ module ActiveFedora
|
|
18
18
|
@terminology
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.default_attributes
|
22
|
-
super.merge(:mimeType => 'text/xml')
|
23
|
-
end
|
24
|
-
|
25
21
|
def self.decorate_ng_xml(xml)
|
26
22
|
xml.set_terminology terminology_options, &terminology
|
27
23
|
xml.nom!
|
@@ -62,6 +58,12 @@ module ActiveFedora
|
|
62
58
|
def respond_to? *args
|
63
59
|
super || self.class.terminology.respond_to?(*args)
|
64
60
|
end
|
61
|
+
|
62
|
+
protected
|
63
|
+
|
64
|
+
def default_mime_type
|
65
|
+
'text/xml'
|
66
|
+
end
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
@@ -152,6 +152,8 @@ module ActiveFedora
|
|
152
152
|
"#{name.to_s.singularize}_ids"
|
153
153
|
elsif options[:as]
|
154
154
|
"#{options[:as]}_id"
|
155
|
+
elsif inverse_of && inverse_of.collection?
|
156
|
+
"#{options[:inverse_of].to_s.singularize}_ids"
|
155
157
|
else
|
156
158
|
# This works well if this is a has_many that is the inverse of a belongs_to, but it isn't correct for a has_many that is the invers of a has_and_belongs_to_many
|
157
159
|
active_fedora.name.foreign_key
|
@@ -292,7 +294,7 @@ module ActiveFedora
|
|
292
294
|
# returns either false or the inverse association name that it finds.
|
293
295
|
def automatic_inverse_of
|
294
296
|
if can_find_inverse_of_automatically?(self)
|
295
|
-
inverse_name = ActiveSupport::Inflector.underscore(active_fedora.name).to_sym
|
297
|
+
inverse_name = ActiveSupport::Inflector.underscore(options[:as] || active_fedora.name.demodulize).to_sym
|
296
298
|
|
297
299
|
begin
|
298
300
|
reflection = klass.reflect_on_association(inverse_name)
|
@@ -38,7 +38,6 @@ module ActiveFedora
|
|
38
38
|
return to_a.find { |*block_args| yield(*block_args) } if block_given?
|
39
39
|
options = args.extract_options!
|
40
40
|
options = options.dup
|
41
|
-
|
42
41
|
cast = if @klass == ActiveFedora::Base && !options.has_key?(:cast)
|
43
42
|
true
|
44
43
|
else
|
@@ -198,12 +197,37 @@ module ActiveFedora
|
|
198
197
|
ActiveFedora::Base
|
199
198
|
else
|
200
199
|
# The true class may be a subclass of @klass, so always use from_class_uri
|
201
|
-
Model.from_class_uri(has_model_value(resource)) || ActiveFedora::Base
|
200
|
+
resource_class = Model.from_class_uri(has_model_value(resource)) || ActiveFedora::Base
|
201
|
+
unless equivalent_class?(resource_class)
|
202
|
+
raise ActiveFedora::ActiveFedoraError.new("Model mismatch. Expected #{@klass}. Got: #{resource_class}")
|
203
|
+
end
|
204
|
+
resource_class
|
202
205
|
end
|
203
206
|
end
|
204
207
|
|
205
208
|
def has_model_value(resource)
|
206
|
-
|
209
|
+
best_model_match = nil
|
210
|
+
|
211
|
+
resource.graph.query([nil, ActiveFedora::RDF::Fcrepo::Model.hasModel, nil]).each do |rg|
|
212
|
+
|
213
|
+
model_value = Model.from_class_uri(rg.object.to_s)
|
214
|
+
|
215
|
+
if model_value
|
216
|
+
|
217
|
+
best_model_match ||= model_value
|
218
|
+
|
219
|
+
# If there is an inheritance structure, use the most specific case.
|
220
|
+
if best_model_match > model_value
|
221
|
+
best_model_match = model_value
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
best_model_match.to_s
|
227
|
+
end
|
228
|
+
|
229
|
+
def equivalent_class?(other_class)
|
230
|
+
other_class <= @klass
|
207
231
|
end
|
208
232
|
|
209
233
|
def find_with_ids(ids, cast)
|
@@ -264,10 +288,10 @@ module ActiveFedora
|
|
264
288
|
if value.empty?
|
265
289
|
"-#{key}:['' TO *]"
|
266
290
|
elsif value.is_a? Array
|
267
|
-
value.map { |val| "#{key}:#{
|
291
|
+
value.map { |val| "#{key}:#{solr_escape(val)}" }
|
268
292
|
else
|
269
293
|
key = SOLR_DOCUMENT_ID if (key === :id || key === :id)
|
270
|
-
"#{key}:#{
|
294
|
+
"#{key}:#{solr_escape(value)}"
|
271
295
|
end
|
272
296
|
end
|
273
297
|
end
|
@@ -283,5 +307,12 @@ module ActiveFedora
|
|
283
307
|
end
|
284
308
|
end
|
285
309
|
|
310
|
+
|
311
|
+
private
|
312
|
+
# Adds esaping for spaces which are not handled by RSolr.solr_escape
|
313
|
+
# See rsolr/rsolr#101
|
314
|
+
def solr_escape terms
|
315
|
+
RSolr.solr_escape(terms).gsub(/\s+/,"\\ ")
|
316
|
+
end
|
286
317
|
end
|
287
318
|
end
|
@@ -2,11 +2,13 @@ module ActiveFedora
|
|
2
2
|
class VersionsGraph < ::RDF::Graph
|
3
3
|
|
4
4
|
def all opts={}
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
fedora_versions.reject { |v| v.label.match("auto") }
|
5
|
+
versions = fedora_versions
|
6
|
+
unless opts[:include_auto_save]
|
7
|
+
versions.reject! { |version| version.label.match("auto") }
|
9
8
|
end
|
9
|
+
versions.sort_by { |version| DateTime.parse(version.created) }
|
10
|
+
rescue ArgumentError, NoMethodError
|
11
|
+
raise ActiveFedora::VersionLacksCreateDate
|
10
12
|
end
|
11
13
|
|
12
14
|
def first
|
@@ -50,10 +52,7 @@ module ActiveFedora
|
|
50
52
|
end
|
51
53
|
|
52
54
|
def fedora_versions
|
53
|
-
|
54
|
-
list.sort_by(&:created)
|
55
|
+
resources.map { |statement| version_from_resource(statement) }
|
55
56
|
end
|
56
|
-
|
57
57
|
end
|
58
|
-
|
59
58
|
end
|
@@ -24,6 +24,37 @@ describe ActiveFedora::Base do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
end
|
27
|
+
|
28
|
+
describe "explicit foreign key" do
|
29
|
+
before do
|
30
|
+
class FooThing < ActiveFedora::Base
|
31
|
+
has_many :bars, :class_name=>'BarThing', :predicate=>ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf, as: :foothing
|
32
|
+
end
|
33
|
+
|
34
|
+
class BarThing < ActiveFedora::Base
|
35
|
+
belongs_to :foothing, :class_name=>'FooThing', :predicate=>ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
after do
|
40
|
+
Object.send(:remove_const, :FooThing)
|
41
|
+
Object.send(:remove_const, :BarThing)
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:foo) { FooThing.create }
|
45
|
+
let(:bar) { BarThing.create }
|
46
|
+
|
47
|
+
it "should associate from bar to foo" do
|
48
|
+
bar.foothing = foo
|
49
|
+
bar.save
|
50
|
+
expect(foo.bars).to eq [bar]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should associate from foo to bar" do
|
54
|
+
foo.bars << bar
|
55
|
+
expect(bar.foothing).to eq foo
|
56
|
+
end
|
57
|
+
end
|
27
58
|
|
28
59
|
describe "complex example" do
|
29
60
|
before do
|
@@ -255,6 +286,39 @@ describe ActiveFedora::Base do
|
|
255
286
|
end
|
256
287
|
end
|
257
288
|
|
289
|
+
describe "when fetching an existing object" do
|
290
|
+
before do
|
291
|
+
class Dog < ActiveFedora::Base; end
|
292
|
+
class BigDog < Dog; end
|
293
|
+
class Cat < ActiveFedora::Base; end
|
294
|
+
@dog = Dog.create
|
295
|
+
@big_dog = BigDog.create
|
296
|
+
end
|
297
|
+
it "should detect class mismatch" do
|
298
|
+
expect {
|
299
|
+
Cat.find @dog.id
|
300
|
+
}.to raise_error(ActiveFedora::ActiveFedoraError)
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should not accept parent class into a subclass" do
|
304
|
+
expect {
|
305
|
+
BigDog.find @dog.id
|
306
|
+
}.to raise_error(ActiveFedora::ActiveFedoraError)
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should accept a subclass into a parent class" do
|
310
|
+
# We could prevent this altogether since loading a subclass into
|
311
|
+
# a parent class (a BigDog into a Dog) would result in lost of
|
312
|
+
# data if the object is saved back and the subclass has more
|
313
|
+
# properties than the parent class. However, it does seem reasonable
|
314
|
+
# that people might want to use them interchangeably (after all
|
315
|
+
# a BigDog is a Dog) and therefore we allow for it.
|
316
|
+
expect {
|
317
|
+
Dog.find @big_dog.id
|
318
|
+
}.not_to raise_error
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
258
322
|
describe "setting belongs_to" do
|
259
323
|
before do
|
260
324
|
@library = Library.new()
|
@@ -527,27 +591,6 @@ describe ActiveFedora::Base do
|
|
527
591
|
expect(MediaObject.new.association(:baubles).send(:find_reflection)).to eq MediaObject.reflect_on_association(:baubles)
|
528
592
|
end
|
529
593
|
end
|
530
|
-
|
531
|
-
describe "an object doesn't have a property" do
|
532
|
-
before :all do
|
533
|
-
class Bauble < ActiveFedora::Base
|
534
|
-
belongs_to :media_object, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.isPartOf
|
535
|
-
end
|
536
|
-
|
537
|
-
class MediaObject < ActiveFedora::Base
|
538
|
-
has_many :shoes
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
|
-
after :all do
|
543
|
-
Object.send(:remove_const, :Bauble)
|
544
|
-
Object.send(:remove_const, :MediaObject)
|
545
|
-
end
|
546
|
-
|
547
|
-
it "it should find the predicate" do
|
548
|
-
expect { MediaObject.new.shoes.send(:find_predicate) }.to raise_error RuntimeError, "No :predicate attribute was set or could be inferred for has_many :shoes on MediaObject"
|
549
|
-
end
|
550
|
-
end
|
551
594
|
end
|
552
595
|
|
553
596
|
describe "casting when the class name is ActiveFedora::Base" do
|
@@ -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
|
|