active-fedora 6.4.0.rc1 → 6.4.0.rc2
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 +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
|