active-fedora 6.4.0.rc1 → 6.4.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/active_fedora/rdf/nested_attributes.rb +57 -15
- data/lib/active_fedora/rdf_datastream.rb +4 -1
- data/lib/active_fedora/rdf_list.rb +4 -0
- data/lib/active_fedora/rdf_node.rb +53 -14
- data/lib/active_fedora/rdf_node/term_proxy.rb +28 -16
- data/lib/active_fedora/version.rb +1 -1
- data/spec/integration/complex_rdf_datastream_spec.rb +17 -0
- data/spec/integration/rdf_nested_attributes_spec.rb +142 -103
- data/spec/unit/ntriples_datastream_spec.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f6463fca15144a94e10e6c80c86871f57867c2b
|
4
|
+
data.tar.gz: d08ad6e9492d3d62fa5227ce779539ffd83406bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 13a56b47d6da5d2c173f67f255a30e5d7bdf1b4e6c1a98cd3cff69390bbe5a463ef3b4e2167976f7ef1c55defa7844224ba6cfa769e38ad057bb49e0fb12c53f
|
7
|
+
data.tar.gz: 64befaef8bdcbb7f54443591ceba0d71d98ceacf5fc303b0e162bf6cdbd38bb8f2709ea52e5e5e19e492591127cb810c09bdb1fb61d90ab0b5bce6624ec7328d
|
@@ -25,19 +25,60 @@ module ActiveFedora
|
|
25
25
|
association = self.send(association_name)
|
26
26
|
|
27
27
|
attributes_collection.each do |attributes|
|
28
|
-
|
28
|
+
attributes = attributes.with_indifferent_access
|
29
|
+
|
30
|
+
if attributes['id'].blank?
|
29
31
|
attributes = attributes.with_indifferent_access
|
30
32
|
association.build(attributes.except(*UNASSIGNABLE_KEYS))
|
33
|
+
elsif existing_record = association.detect { |record| record.rdf_subject.to_s == attributes['id'].to_s }
|
34
|
+
if !call_reject_if(association_name, attributes)
|
35
|
+
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
|
36
|
+
end
|
31
37
|
else
|
32
|
-
|
38
|
+
raise_nested_attributes_record_not_found(association_name, record.rdf_subject.to_s)
|
33
39
|
end
|
34
40
|
end
|
35
41
|
end
|
36
42
|
|
43
|
+
# Updates a record with the +attributes+ or marks it for destruction if
|
44
|
+
# +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
|
45
|
+
def assign_to_or_mark_for_destruction(record, attributes, allow_destroy)
|
46
|
+
record.attributes = attributes.except(*UNASSIGNABLE_KEYS)
|
47
|
+
record.mark_for_destruction if has_destroy_flag?(attributes) && allow_destroy
|
48
|
+
end
|
49
|
+
|
50
|
+
def raise_nested_attributes_record_not_found(association_name, record_id)
|
51
|
+
raise RecordNotFound, "Couldn't find #{association_name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def call_reject_if(association_name, attributes)
|
55
|
+
return false if has_destroy_flag?(attributes)
|
56
|
+
case callback = self.nested_attributes_options[association_name][:reject_if]
|
57
|
+
when Symbol
|
58
|
+
method(callback).arity == 0 ? send(callback) : send(callback, attributes)
|
59
|
+
when Proc
|
60
|
+
callback.call(attributes)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Determines if a hash contains a truthy _destroy key.
|
65
|
+
def has_destroy_flag?(hash)
|
66
|
+
["1", "true"].include?(hash['_destroy'].to_s)
|
67
|
+
end
|
68
|
+
|
69
|
+
|
37
70
|
module ClassMethods
|
38
|
-
def accepts_nested_attributes_for *
|
39
|
-
|
40
|
-
|
71
|
+
def accepts_nested_attributes_for *attr_names
|
72
|
+
options = { :allow_destroy => false, :update_only => false }
|
73
|
+
options.update(attr_names.extract_options!)
|
74
|
+
options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
|
75
|
+
options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
|
76
|
+
|
77
|
+
attr_names.each do |association_name|
|
78
|
+
nested_attributes_options = self.nested_attributes_options.dup
|
79
|
+
nested_attributes_options[association_name] = options
|
80
|
+
self.nested_attributes_options = nested_attributes_options
|
81
|
+
|
41
82
|
generate_association_writer(association_name)
|
42
83
|
end
|
43
84
|
end
|
@@ -56,16 +97,17 @@ module ActiveFedora
|
|
56
97
|
# the helper methods defined below. Makes it seem like the nested
|
57
98
|
# associations are just regular associations.
|
58
99
|
def generate_association_writer(association_name)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
100
|
+
class_eval <<-eoruby, __FILE__, __LINE__ + 1
|
101
|
+
if method_defined?(:#{association_name}_attributes=)
|
102
|
+
remove_method(:#{association_name}_attributes=)
|
103
|
+
end
|
104
|
+
def #{association_name}_attributes=(attributes)
|
105
|
+
assign_nested_attributes_for_collection_association(:#{association_name}, attributes)
|
106
|
+
## in lieu of autosave_association_callbacks just save all of em.
|
107
|
+
send(:#{association_name}).each {|obj| obj.marked_for_destruction? ? obj.destroy : nil}
|
108
|
+
send(:#{association_name}).reset!
|
109
|
+
end
|
110
|
+
eoruby
|
69
111
|
end
|
70
112
|
end
|
71
113
|
end
|
@@ -42,6 +42,7 @@ module ActiveFedora
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def content=(content)
|
45
|
+
reset_child_cache!
|
45
46
|
@graph = deserialize(content)
|
46
47
|
end
|
47
48
|
|
@@ -98,6 +99,7 @@ module ActiveFedora
|
|
98
99
|
# Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
|
99
100
|
def serialize
|
100
101
|
update_subjects_to_use_a_real_pid!
|
102
|
+
|
101
103
|
RDF::Writer.for(serialization_format).dump(graph)
|
102
104
|
end
|
103
105
|
|
@@ -109,6 +111,7 @@ module ActiveFedora
|
|
109
111
|
|
110
112
|
bad_subject = rdf_subject
|
111
113
|
reset_rdf_subject!
|
114
|
+
reset_child_cache!
|
112
115
|
new_subject = rdf_subject
|
113
116
|
|
114
117
|
new_repository = RDF::Repository.new
|
@@ -125,7 +128,7 @@ module ActiveFedora
|
|
125
128
|
|
126
129
|
# returns a Hash, e.g.: {field => {:values => [], :type => :something, :behaviors => []}, ...}
|
127
130
|
def fields
|
128
|
-
field_map = {}
|
131
|
+
field_map = {}.with_indifferent_access
|
129
132
|
|
130
133
|
rdf_subject = self.rdf_subject
|
131
134
|
query = RDF::Query.new do
|
@@ -36,12 +36,17 @@ module ActiveFedora
|
|
36
36
|
@subject = nil
|
37
37
|
end
|
38
38
|
|
39
|
+
def reset_child_cache!
|
40
|
+
@target = {}
|
41
|
+
end
|
42
|
+
|
39
43
|
# @param [RDF::URI] subject the base node to start the search from
|
40
44
|
# @param [Symbol] term the term to get the values for
|
41
45
|
def get_values(subject, term)
|
42
46
|
options = config_for_term_or_uri(term)
|
43
47
|
predicate = options[:predicate]
|
44
|
-
|
48
|
+
@target ||= {}
|
49
|
+
@target[term.to_s] ||= TermProxy.new(self, subject, predicate, options)
|
45
50
|
end
|
46
51
|
|
47
52
|
def target_class(predicate)
|
@@ -51,12 +56,20 @@ module ActiveFedora
|
|
51
56
|
ActiveFedora.class_from_string(class_name, self.class)
|
52
57
|
end
|
53
58
|
|
59
|
+
def mark_for_destruction
|
60
|
+
@marked_for_destruction = true
|
61
|
+
end
|
62
|
+
|
63
|
+
def marked_for_destruction?
|
64
|
+
@marked_for_destruction
|
65
|
+
end
|
66
|
+
|
54
67
|
# if there are any existing statements with this predicate, replace them
|
55
68
|
# @param [RDF::URI] subject the subject to insert into the graph
|
56
69
|
# @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
|
57
70
|
# @param [Array,#to_s] values the value/values to insert into the graph
|
58
|
-
def set_value(subject,
|
59
|
-
options = config_for_term_or_uri(
|
71
|
+
def set_value(subject, term, values)
|
72
|
+
options = config_for_term_or_uri(term)
|
60
73
|
predicate = options[:predicate]
|
61
74
|
values = Array(values)
|
62
75
|
|
@@ -71,20 +84,46 @@ module ActiveFedora
|
|
71
84
|
end
|
72
85
|
end
|
73
86
|
|
74
|
-
|
87
|
+
@target ||= {}
|
88
|
+
proxy = @target[term.to_s]
|
89
|
+
proxy ||= TermProxy.new(self, subject, predicate, options)
|
90
|
+
proxy.reset!
|
91
|
+
proxy
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
# Be careful with destroy. It will still be in the cache untill you call reset()
|
96
|
+
def destroy
|
97
|
+
# delete any statements about this rdf_subject
|
98
|
+
subject = rdf_subject
|
99
|
+
query = RDF::Query.new do
|
100
|
+
pattern [subject, :predicate, :value]
|
101
|
+
end
|
102
|
+
|
103
|
+
query.execute(graph).each do |solution|
|
104
|
+
graph.delete [subject, solution.predicate, solution.value]
|
105
|
+
end
|
106
|
+
|
107
|
+
# delete any statements that reference this rdf_subject
|
108
|
+
query = RDF::Query.new do
|
109
|
+
pattern [:subject, :predicate, subject]
|
110
|
+
end
|
111
|
+
|
112
|
+
query.execute(graph).each do |solution|
|
113
|
+
graph.delete [solution.subject, solution.predicate, subject]
|
114
|
+
end
|
75
115
|
end
|
76
116
|
|
77
117
|
# @option [Hash] values the values to assign to this rdf node.
|
78
118
|
def attributes=(values)
|
79
119
|
raise ArgumentError, "values must be a Hash, you provided #{values.class}" unless values.kind_of? Hash
|
80
|
-
|
81
|
-
if
|
82
|
-
set_value(rdf_subject, key,
|
120
|
+
values.with_indifferent_access.each do |key, value|
|
121
|
+
if self.class.config.keys.include?(key)
|
122
|
+
set_value(rdf_subject, key, value)
|
123
|
+
elsif nested_attributes_options.keys.map{ |k| "#{k}_attributes"}.include?(key)
|
124
|
+
send("#{key}=".to_sym, value)
|
83
125
|
end
|
84
126
|
end
|
85
|
-
nested_attributes_options.keys.each do |key|
|
86
|
-
send("#{key}_attributes=".to_sym, values["#{key}_attributes".to_sym])
|
87
|
-
end
|
88
127
|
end
|
89
128
|
|
90
129
|
def delete_predicate(subject, predicate, values = nil)
|
@@ -103,6 +142,7 @@ module ActiveFedora
|
|
103
142
|
graph.delete [subject, predicate, v]
|
104
143
|
end
|
105
144
|
end
|
145
|
+
reset_child_cache!
|
106
146
|
end
|
107
147
|
|
108
148
|
# append a value
|
@@ -110,7 +150,6 @@ module ActiveFedora
|
|
110
150
|
def append(subject, predicate, args)
|
111
151
|
options = config_for_term_or_uri(predicate)
|
112
152
|
graph.insert([subject, predicate, args])
|
113
|
-
TermProxy.new(self, subject, options[:predicate], options)
|
114
153
|
end
|
115
154
|
|
116
155
|
def config_for_term_or_uri(term)
|
@@ -139,8 +178,8 @@ module ActiveFedora
|
|
139
178
|
end
|
140
179
|
|
141
180
|
def method_missing(name, *args)
|
142
|
-
if
|
143
|
-
set_value(rdf_subject,
|
181
|
+
if md = /^([^=]+)=$/.match(name.to_s)
|
182
|
+
set_value(rdf_subject, md[1], *args)
|
144
183
|
elsif find_predicate(name)
|
145
184
|
get_values(rdf_subject, name)
|
146
185
|
else
|
@@ -244,7 +283,7 @@ module ActiveFedora
|
|
244
283
|
|
245
284
|
module ClassMethods
|
246
285
|
def config
|
247
|
-
@config ||= {}
|
286
|
+
@config ||= {}.with_indifferent_access
|
248
287
|
end
|
249
288
|
|
250
289
|
def map_predicates(&block)
|
@@ -2,45 +2,57 @@ module ActiveFedora
|
|
2
2
|
module RdfNode
|
3
3
|
class TermProxy
|
4
4
|
|
5
|
-
attr_reader :
|
6
|
-
|
7
|
-
|
5
|
+
attr_reader :parent, :subject, :predicate, :options
|
6
|
+
delegate *(Array.public_instance_methods - [:__send__, :__id__, :class, :object_id] + [:as_json]), :to => :target
|
7
|
+
|
8
8
|
|
9
|
-
# @param
|
9
|
+
# @param parent RdfNode
|
10
10
|
# @param subject RDF::URI
|
11
11
|
# @param options Hash
|
12
|
-
def initialize(
|
13
|
-
@
|
12
|
+
def initialize(parent, subject, predicate, options)
|
13
|
+
@parent = parent
|
14
14
|
@subject = subject
|
15
15
|
@predicate = predicate
|
16
16
|
@options = options
|
17
17
|
end
|
18
18
|
|
19
|
+
|
19
20
|
def build(attributes=nil)
|
20
21
|
new_subject = RDF::Node.new
|
21
|
-
|
22
|
-
|
22
|
+
parent.graph.insert([subject, predicate, new_subject])
|
23
|
+
parent.target_class(predicate).new(parent.graph, new_subject).tap do |node|
|
23
24
|
node.attributes = attributes if attributes
|
24
25
|
end
|
26
|
+
reset!
|
27
|
+
target.find { |n| n.rdf_subject == new_subject}
|
28
|
+
end
|
29
|
+
|
30
|
+
def reset!
|
31
|
+
@target = nil
|
25
32
|
end
|
26
33
|
|
27
34
|
def <<(*values)
|
28
|
-
values.each { |value|
|
35
|
+
values.each { |value| parent.append(subject, predicate, value) }
|
36
|
+
reset!
|
29
37
|
values
|
30
38
|
end
|
31
39
|
|
32
40
|
def delete(*values)
|
33
41
|
values.each do |value|
|
34
|
-
|
42
|
+
parent.delete_predicate(subject, predicate, value)
|
35
43
|
end
|
36
44
|
|
37
45
|
values
|
38
46
|
end
|
39
47
|
|
40
|
-
def
|
48
|
+
def target
|
49
|
+
@target ||= load_values
|
50
|
+
end
|
51
|
+
|
52
|
+
def load_values
|
41
53
|
values = []
|
42
54
|
|
43
|
-
|
55
|
+
parent.query(subject, predicate).each do |solution|
|
44
56
|
v = solution.value
|
45
57
|
v = v.to_s if v.is_a? RDF::Literal
|
46
58
|
if options[:type] == :date
|
@@ -50,14 +62,14 @@ module ActiveFedora
|
|
50
62
|
# potential solution is of the right RDF.type
|
51
63
|
if options[:class_name]
|
52
64
|
klass = class_from_rdf_type(v)
|
53
|
-
values << v if klass == ActiveFedora.class_from_string(options[:class_name],
|
65
|
+
values << v if klass == ActiveFedora.class_from_string(options[:class_name], parent.class)
|
54
66
|
else
|
55
67
|
values << v
|
56
68
|
end
|
57
69
|
end
|
58
70
|
|
59
71
|
if options[:class_name]
|
60
|
-
values = values.map{ |found_subject| class_from_rdf_type(found_subject).new(
|
72
|
+
values = values.map{ |found_subject| class_from_rdf_type(found_subject).new(parent.graph, found_subject)}
|
61
73
|
end
|
62
74
|
|
63
75
|
values
|
@@ -66,7 +78,7 @@ module ActiveFedora
|
|
66
78
|
private
|
67
79
|
|
68
80
|
def target_class
|
69
|
-
|
81
|
+
parent.target_class(predicate)
|
70
82
|
end
|
71
83
|
|
72
84
|
# Look for a RDF.type assertion on this node to see if an RDF class is specified.
|
@@ -78,7 +90,7 @@ module ActiveFedora
|
|
78
90
|
end
|
79
91
|
|
80
92
|
type_uri = []
|
81
|
-
q.execute(
|
93
|
+
q.execute(parent.graph).each do |sol|
|
82
94
|
type_uri << sol.value
|
83
95
|
end
|
84
96
|
|
@@ -35,6 +35,23 @@ describe "Nested Rdf Objects" do
|
|
35
35
|
ds.parts.first.label.should == ["Alternator"]
|
36
36
|
end
|
37
37
|
|
38
|
+
it "should be able to replace attributes" do
|
39
|
+
v = ds.parts.build(label: 'Alternator')
|
40
|
+
ds.parts.first.label.should == ['Alternator']
|
41
|
+
ds.parts.first.label = ['Distributor']
|
42
|
+
ds.parts.first.label.should == ['Distributor']
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should be able to replace objects" do
|
46
|
+
ds.parts.build(label: 'Alternator')
|
47
|
+
ds.parts.build(label: 'Distributor')
|
48
|
+
ds.parts.size.should == 2
|
49
|
+
comp = SpecDatastream::Component.new(ds.graph)
|
50
|
+
comp.label = "Injector port"
|
51
|
+
ds.parts = [comp]
|
52
|
+
ds.parts.size.should == 1
|
53
|
+
end
|
54
|
+
|
38
55
|
it "should be able to nest many complex objects" do
|
39
56
|
comp1 = SpecDatastream::Component.new ds.graph
|
40
57
|
comp1.label = ["Alternator"]
|
@@ -1,118 +1,157 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
class ComplexRDFDatastream < ActiveFedora::NtriplesRDFDatastream
|
26
|
-
map_predicates do |map|
|
27
|
-
map.topic(in: DummyMADS, to: "Topic", class_name:"Topic")
|
28
|
-
map.personalName(in: DummyMADS, to: "PersonalName", class_name:"PersonalName")
|
29
|
-
map.title(in: RDF::DC)
|
3
|
+
describe "Nesting attribute behavior of RDFDatastream" do
|
4
|
+
describe ".attributes=" do
|
5
|
+
describe "complex properties" do
|
6
|
+
before do
|
7
|
+
class DummyMADS < RDF::Vocabulary("http://www.loc.gov/mads/rdf/v1#")
|
8
|
+
# componentList and Types of components
|
9
|
+
property :componentList
|
10
|
+
property :Topic
|
11
|
+
property :Temporal
|
12
|
+
property :PersonalName
|
13
|
+
property :CorporateName
|
14
|
+
property :ComplexSubject
|
15
|
+
|
16
|
+
|
17
|
+
# elementList and elementList values
|
18
|
+
property :elementList
|
19
|
+
property :elementValue
|
20
|
+
property :TopicElement
|
21
|
+
property :TemporalElement
|
22
|
+
property :NameElement
|
23
|
+
property :FullNameElement
|
24
|
+
property :DateNameElement
|
30
25
|
end
|
31
26
|
|
32
|
-
|
33
|
-
|
34
|
-
class Topic
|
35
|
-
include ActiveFedora::RdfObject
|
27
|
+
class ComplexRDFDatastream < ActiveFedora::NtriplesRDFDatastream
|
36
28
|
map_predicates do |map|
|
37
|
-
map.
|
29
|
+
map.topic(in: DummyMADS, to: "Topic", class_name:"Topic")
|
30
|
+
map.personalName(in: DummyMADS, to: "PersonalName", class_name:"PersonalName")
|
31
|
+
map.title(in: RDF::DC)
|
38
32
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
33
|
+
|
34
|
+
accepts_nested_attributes_for :topic, :personalName
|
35
|
+
|
36
|
+
class Topic
|
37
|
+
include ActiveFedora::RdfObject
|
38
|
+
map_predicates do |map|
|
39
|
+
map.elementList(in: DummyMADS, class_name:"ComplexRDFDatastream::ElementList")
|
40
|
+
end
|
41
|
+
accepts_nested_attributes_for :elementList
|
46
42
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
map
|
43
|
+
class PersonalName
|
44
|
+
include ActiveFedora::RdfObject
|
45
|
+
map_predicates do |map|
|
46
|
+
map.elementList(in: DummyMADS, to: "elementList", class_name:"ComplexRDFDatastream::ElementList")
|
47
|
+
map.extraProperty(in: DummyMADS, to: "elementValue", class_name:"ComplexRDFDatastream::Topic")
|
48
|
+
end
|
49
|
+
accepts_nested_attributes_for :elementList, :extraProperty
|
50
|
+
end
|
51
|
+
class ElementList
|
52
|
+
include ActiveFedora::RdfObject
|
53
|
+
rdf_type DummyMADS.elementList
|
54
|
+
map_predicates do |map|
|
55
|
+
map.topicElement(in: DummyMADS, to: "TopicElement")
|
56
|
+
map.temporalElement(in: DummyMADS, to: "TemporalElement")
|
57
|
+
map.fullNameElement(in: DummyMADS, to: "FullNameElement")
|
58
|
+
map.dateNameElement(in: DummyMADS, to: "DateNameElement")
|
59
|
+
map.nameElement(in: DummyMADS, to: "NameElement")
|
60
|
+
map.elementValue(in: DummyMADS)
|
61
|
+
end
|
59
62
|
end
|
60
63
|
end
|
61
64
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
}
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}
|
92
|
-
}
|
93
|
-
#, "Hemings, Sally"
|
94
|
-
],
|
95
|
-
}
|
65
|
+
after do
|
66
|
+
Object.send(:remove_const, :ComplexRDFDatastream)
|
67
|
+
Object.send(:remove_const, :DummyMADS)
|
68
|
+
end
|
69
|
+
subject { ComplexRDFDatastream.new(stub('inner object', :pid=>'foo', :new? =>true), 'descMetadata') }
|
70
|
+
let(:params) do
|
71
|
+
{ myResource:
|
72
|
+
{
|
73
|
+
topic_attributes: [
|
74
|
+
{
|
75
|
+
elementList_attributes: [{
|
76
|
+
topicElement:"Cosmology"
|
77
|
+
}]
|
78
|
+
},
|
79
|
+
{
|
80
|
+
elementList_attributes: [{
|
81
|
+
topicElement:"Quantum Behavior"
|
82
|
+
}]
|
83
|
+
}
|
84
|
+
],
|
85
|
+
personalName_attributes: [
|
86
|
+
{
|
87
|
+
elementList_attributes: [{
|
88
|
+
fullNameElement: "Jefferson, Thomas",
|
89
|
+
dateNameElement: "1743-1826"
|
90
|
+
}]
|
91
|
+
}
|
92
|
+
#, "Hemings, Sally"
|
93
|
+
],
|
96
94
|
}
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
95
|
+
}
|
96
|
+
end
|
97
|
+
it "should create nested objects" do
|
98
|
+
# Replace the graph's contents with the Hash
|
99
|
+
subject.attributes = params[:myResource]
|
101
100
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
101
|
+
# Here's how this would happen if we didn't have attributes=
|
102
|
+
# personal_name = subject.personalName.build
|
103
|
+
# elem_list = personal_name.elementList.build
|
104
|
+
# elem_list.fullNameElement = "Jefferson, Thomas"
|
105
|
+
# elem_list.dateNameElement = "1743-1826"
|
106
|
+
# topic = subject.topic.build
|
107
|
+
# elem_list = topic.elementList.build
|
108
|
+
# elem_list.fullNameElement = 'Cosmology'
|
110
109
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
end
|
110
|
+
subject.topic.first.elementList.first.topicElement.should == ["Cosmology"]
|
111
|
+
subject.topic[1].elementList.first.topicElement.should == ["Quantum Behavior"]
|
112
|
+
subject.personalName.first.elementList.first.fullNameElement.should == ["Jefferson, Thomas"]
|
113
|
+
subject.personalName.first.elementList.first.dateNameElement.should == ["1743-1826"]
|
114
|
+
end
|
117
115
|
end
|
116
|
+
|
117
|
+
describe "with an existing object" do
|
118
|
+
before(:each) do
|
119
|
+
class SpecDatastream < ActiveFedora::NtriplesRDFDatastream
|
120
|
+
map_predicates do |map|
|
121
|
+
map.parts(:in=> RDF::DC, :to=>'hasPart', :class_name=>'Component')
|
122
|
+
end
|
123
|
+
accepts_nested_attributes_for :parts, allow_destroy: true
|
124
|
+
|
125
|
+
class Component
|
126
|
+
include ActiveFedora::RdfObject
|
127
|
+
map_predicates do |map|
|
128
|
+
map.label(:in=> RDF::DC, :to=>'title')
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
after(:each) do
|
136
|
+
Object.send(:remove_const, :SpecDatastream)
|
137
|
+
end
|
138
|
+
subject { SpecDatastream.new(stub('inner object', :pid=>'foo', :new? =>true), 'descMetadata') }
|
139
|
+
before do
|
140
|
+
subject.attributes = { parts_attributes: [
|
141
|
+
{label: 'Alternator'},
|
142
|
+
{label: 'Distributor'},
|
143
|
+
{label: 'Transmission'},
|
144
|
+
{label: 'Fuel Filter'}]}
|
145
|
+
end
|
146
|
+
let (:replace_object_id) { subject.parts[1].rdf_subject.to_s }
|
147
|
+
let (:remove_object_id) { subject.parts[3].rdf_subject.to_s }
|
148
|
+
|
149
|
+
it "should update nested objects" do
|
150
|
+
subject.parts_attributes= [{id: replace_object_id, label: "Universal Joint"}, {label:"Oil Pump"}, {id: remove_object_id, _destroy: '1', label: "bar1 uno"}]
|
151
|
+
|
152
|
+
subject.parts.map{|p| p.label.first}.should == ['Alternator', 'Universal Joint', 'Transmission', 'Oil Pump']
|
153
|
+
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
118
157
|
end
|
@@ -223,7 +223,7 @@ describe ActiveFedora::NtriplesRDFDatastream do
|
|
223
223
|
|
224
224
|
describe ".fields()" do
|
225
225
|
it "should return the right fields" do
|
226
|
-
@obj.send(:fields).keys.should == [
|
226
|
+
@obj.send(:fields).keys.should == ["created", "title", "publisher", "based_near", "related_url"]
|
227
227
|
end
|
228
228
|
it "should return the right values" do
|
229
229
|
fields = @obj.send(:fields)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active-fedora
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.4.0.
|
4
|
+
version: 6.4.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Zumwalt
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-06-
|
13
|
+
date: 2013-06-24 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rsolr
|