active-fedora 9.9.1 → 9.10.0.pre1
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/.rubocop.yml +4 -2
- data/.travis.yml +2 -6
- data/active-fedora.gemspec +9 -6
- data/lib/active_fedora.rb +31 -15
- data/lib/active_fedora/associations.rb +1 -1
- data/lib/active_fedora/associations/association.rb +6 -2
- data/lib/active_fedora/associations/belongs_to_association.rb +0 -10
- data/lib/active_fedora/associations/builder/association.rb +85 -12
- data/lib/active_fedora/associations/builder/belongs_to.rb +3 -1
- data/lib/active_fedora/associations/builder/collection_association.rb +4 -3
- data/lib/active_fedora/associations/builder/contains.rb +7 -2
- data/lib/active_fedora/associations/builder/directly_contains.rb +7 -3
- data/lib/active_fedora/associations/builder/directly_contains_one.rb +8 -4
- data/lib/active_fedora/associations/builder/has_and_belongs_to_many.rb +6 -2
- data/lib/active_fedora/associations/builder/has_many.rb +6 -2
- data/lib/active_fedora/associations/builder/indirectly_contains.rb +7 -3
- data/lib/active_fedora/associations/builder/property.rb +7 -2
- data/lib/active_fedora/associations/builder/singular_association.rb +3 -1
- data/lib/active_fedora/associations/builder/singular_property.rb +3 -1
- data/lib/active_fedora/associations/collection_association.rb +9 -5
- data/lib/active_fedora/associations/collection_proxy.rb +1 -1
- data/lib/active_fedora/associations/contained_finder.rb +1 -2
- data/lib/active_fedora/associations/directly_contains_one_association.rb +1 -1
- data/lib/active_fedora/associations/has_many_association.rb +1 -5
- data/lib/active_fedora/associations/rdf.rb +1 -20
- data/lib/active_fedora/attached_files.rb +1 -1
- data/lib/active_fedora/attribute_methods.rb +18 -0
- data/lib/active_fedora/attributes.rb +1 -1
- data/lib/active_fedora/autosave_association.rb +8 -12
- data/lib/active_fedora/base.rb +0 -2
- data/lib/active_fedora/caching_connection.rb +1 -1
- data/lib/active_fedora/default_model_mapper.rb +24 -0
- data/lib/active_fedora/fedora.rb +1 -1
- data/lib/active_fedora/file/attributes.rb +4 -5
- data/lib/active_fedora/identifiable.rb +5 -0
- data/lib/active_fedora/indexing.rb +13 -7
- data/lib/active_fedora/indexing_service.rb +4 -4
- data/lib/active_fedora/ldp_resource.rb +1 -0
- data/lib/active_fedora/model.rb +18 -16
- data/lib/active_fedora/model_classifier.rb +77 -0
- data/lib/active_fedora/nested_attributes.rb +145 -18
- data/lib/active_fedora/persistence.rb +1 -1
- data/lib/active_fedora/predicates.rb +3 -0
- data/lib/active_fedora/qualified_dublin_core_datastream.rb +1 -1
- data/lib/active_fedora/query_result_builder.rb +12 -28
- data/lib/active_fedora/querying.rb +1 -1
- data/lib/active_fedora/rdf/datastream_indexing.rb +1 -1
- data/lib/active_fedora/reflection.rb +15 -7
- data/lib/active_fedora/relation.rb +17 -0
- data/lib/active_fedora/relation/calculations.rb +1 -5
- data/lib/active_fedora/relation/finder_methods.rb +39 -26
- data/lib/active_fedora/scoping.rb +5 -0
- data/lib/active_fedora/scoping/default.rb +113 -0
- data/lib/active_fedora/scoping/named.rb +11 -3
- data/lib/active_fedora/simple_datastream.rb +1 -1
- data/lib/active_fedora/solr_hit.rb +71 -0
- data/lib/active_fedora/solr_instance_loader.rb +12 -36
- data/lib/active_fedora/solr_query_builder.rb +20 -25
- data/lib/active_fedora/solr_service.rb +24 -13
- data/lib/active_fedora/type.rb +8 -0
- data/lib/active_fedora/type/boolean.rb +23 -0
- data/lib/active_fedora/type/value.rb +118 -0
- data/lib/active_fedora/validations.rb +14 -5
- data/lib/active_fedora/version.rb +1 -1
- data/lib/active_fedora/versionable.rb +8 -7
- data/spec/config_helper.rb +0 -5
- data/spec/integration/associations_spec.rb +5 -5
- data/spec/integration/base_spec.rb +4 -4
- data/spec/integration/bug_spec.rb +0 -1
- data/spec/integration/full_featured_model_spec.rb +4 -4
- data/spec/integration/has_and_belongs_to_many_associations_spec.rb +1 -1
- data/spec/integration/has_many_associations_spec.rb +30 -1
- data/spec/integration/indirect_container_spec.rb +1 -1
- data/spec/integration/nested_attribute_spec.rb +6 -0
- data/spec/integration/ntriples_datastream_spec.rb +4 -4
- data/spec/integration/om_datastream_spec.rb +1 -1
- data/spec/integration/relation_delegation_spec.rb +1 -1
- data/spec/integration/scoped_query_spec.rb +12 -12
- data/spec/integration/solr_hit_spec.rb +52 -0
- data/spec/samples/hydra-mods_article_datastream.rb +2 -2
- data/spec/spec_helper.rb +5 -9
- data/spec/unit/active_fedora_spec.rb +0 -26
- data/spec/unit/base_spec.rb +20 -0
- data/spec/unit/builder/has_and_belongs_to_many_spec.rb +2 -3
- data/spec/unit/callback_spec.rb +3 -8
- data/spec/unit/default_model_mapper_spec.rb +39 -0
- data/spec/unit/finder_methods_spec.rb +30 -6
- data/spec/unit/has_many_association_spec.rb +23 -1
- data/spec/unit/indexing_spec.rb +17 -3
- data/spec/unit/model_classifier_spec.rb +49 -0
- data/spec/unit/model_spec.rb +0 -9
- data/spec/unit/ntriples_datastream_spec.rb +16 -16
- data/spec/unit/om_datastream_spec.rb +7 -7
- data/spec/unit/qualified_dublin_core_datastream_spec.rb +1 -1
- data/spec/unit/query_result_builder_spec.rb +4 -10
- data/spec/unit/query_spec.rb +28 -28
- data/spec/unit/rdf/indexing_service_spec.rb +16 -16
- data/spec/unit/scoping_spec.rb +67 -0
- data/spec/unit/simple_datastream_spec.rb +2 -2
- data/spec/unit/solr_config_options_spec.rb +29 -32
- data/spec/unit/solr_hit_spec.rb +58 -0
- data/spec/unit/solr_query_builder_spec.rb +9 -1
- data/spec/unit/solr_service_spec.rb +19 -3
- metadata +73 -17
- data/spec/support/freeze_mocks.rb +0 -12
@@ -16,15 +16,15 @@ module ActiveFedora
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.profile_solr_name
|
19
|
-
@profile_solr_name ||= ActiveFedora
|
19
|
+
@profile_solr_name ||= ActiveFedora.index_field_mapper.solr_name("object_profile", :displayable)
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.create_time_solr_name
|
23
|
-
@create_time_solr_name ||= ActiveFedora
|
23
|
+
@create_time_solr_name ||= ActiveFedora.index_field_mapper.solr_name('system_create', :stored_sortable, type: :date)
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.modified_time_solr_name
|
27
|
-
@modified_time_solr_name ||= ActiveFedora
|
27
|
+
@modified_time_solr_name ||= ActiveFedora.index_field_mapper.solr_name('system_modified', :stored_sortable, type: :date)
|
28
28
|
end
|
29
29
|
|
30
30
|
def rdf_service
|
@@ -40,7 +40,7 @@ module ActiveFedora
|
|
40
40
|
Solrizer.set_field(solr_doc, 'system_modified', m_time, :stored_sortable)
|
41
41
|
Solrizer.set_field(solr_doc, 'active_fedora_model', object.class.inspect, :stored_sortable)
|
42
42
|
solr_doc[QueryResultBuilder::HAS_MODEL_SOLR_FIELD] = object.has_model
|
43
|
-
solr_doc[
|
43
|
+
solr_doc[ActiveFedora.id_field.to_sym] = object.id
|
44
44
|
solr_doc[self.class.profile_solr_name] = profile_service.new(object).export
|
45
45
|
object.declared_attached_files.each do |name, file|
|
46
46
|
solr_doc.merge! file.to_solr(solr_doc, name: name.to_s)
|
@@ -16,6 +16,7 @@ module ActiveFedora
|
|
16
16
|
# @param [RDF::Graph] original_graph The graph returned by the LDP server
|
17
17
|
# @return [RDF::Graph] A graph striped of any inlined resources present in the original
|
18
18
|
def build_graph(original_graph)
|
19
|
+
Deprecation.warn(ActiveFedora::LdpResource, '#build_graph is deprecated and will be removed in active-fedora 10.0')
|
19
20
|
inlined_resources = get.graph.query(predicate: Ldp.contains).map(&:object)
|
20
21
|
|
21
22
|
# ActiveFedora always wants to copy the resources to a new graph because it
|
data/lib/active_fedora/model.rb
CHANGED
@@ -1,29 +1,31 @@
|
|
1
|
-
SOLR_DOCUMENT_ID = "id".freeze unless defined?(SOLR_DOCUMENT_ID)
|
2
|
-
|
3
1
|
module ActiveFedora
|
4
2
|
# = ActiveFedora
|
5
3
|
# This module mixes various methods into the including class,
|
6
4
|
# much in the way ActiveRecord does.
|
7
5
|
module Model
|
6
|
+
# @deprecated
|
7
|
+
# Convenience method for getting class constant based on a string
|
8
|
+
# @example
|
9
|
+
# ActiveFedora::Model.class_from_string("Om")
|
10
|
+
# => Om
|
11
|
+
# ActiveFedora::Model.class_from_string("ActiveFedora::RdfNode::TermProxy")
|
12
|
+
# => ActiveFedora::RdfNode::TermProxy
|
13
|
+
# @example Search within ActiveFedora::RdfNode for a class called "TermProxy"
|
14
|
+
# ActiveFedora::Model.class_from_string("TermProxy", ActiveFedora::RdfNode)
|
15
|
+
# => ActiveFedora::RdfNode::TermProxy
|
16
|
+
def self.class_from_string(*args)
|
17
|
+
Deprecation.warn("ActiveFedora::Model.class_from_string has been deprecated and will be removed in ActiveFedora 10.0. Use ActiveFedora::ModelClassifier.class_from_string instead")
|
18
|
+
ActiveFedora::ModelClassifier.class_from_string(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @deprecated
|
8
22
|
# Takes a Fedora URI for a cModel, and returns a
|
9
23
|
# corresponding Model if available
|
10
24
|
# This method should reverse ClassMethods#to_class_uri
|
11
25
|
# @return [Class, False] the class of the model or false, if it does not exist
|
12
26
|
def self.from_class_uri(model_value)
|
13
|
-
|
14
|
-
|
15
|
-
return nil
|
16
|
-
end
|
17
|
-
ActiveFedora.class_from_string(model_value)
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.class_exists?(class_name)
|
21
|
-
return false if class_name.empty?
|
22
|
-
klass = class_name.constantize
|
23
|
-
return klass.is_a?(Class)
|
24
|
-
rescue NameError
|
25
|
-
return false
|
27
|
+
Deprecation.warn("ActiveFedora::Model.from_class_uri has been deprecated and will be removed in ActiveFedora 10.0. Use ActiveFedora::ModelClassifier.from_class_uri instead")
|
28
|
+
ActiveFedora::ModelClassifier.new(Array(model_value)).best_model
|
26
29
|
end
|
27
|
-
private_class_method :class_exists?
|
28
30
|
end
|
29
31
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module ActiveFedora
|
2
|
+
# Translate model names to classes
|
3
|
+
class ModelClassifier
|
4
|
+
# Convenience method for getting class constant based on a string
|
5
|
+
# @example
|
6
|
+
# ActiveFedora::Model.class_from_string("Om")
|
7
|
+
# => Om
|
8
|
+
# ActiveFedora::Model.class_from_string("ActiveFedora::RdfNode::TermProxy")
|
9
|
+
# => ActiveFedora::RdfNode::TermProxy
|
10
|
+
# @example Search within ActiveFedora::RdfNode for a class called "TermProxy"
|
11
|
+
# ActiveFedora::Model.class_from_string("TermProxy", ActiveFedora::RdfNode)
|
12
|
+
# => ActiveFedora::RdfNode::TermProxy
|
13
|
+
def self.class_from_string(full_class_name, container_class = Kernel)
|
14
|
+
container_class = container_class.name if container_class.is_a? Module
|
15
|
+
container_parts = container_class.split('::')
|
16
|
+
(container_parts + full_class_name.split('::')).flatten.inject(Kernel) do |mod, class_name|
|
17
|
+
if mod == Kernel
|
18
|
+
Object.const_get(class_name)
|
19
|
+
elsif mod.const_defined? class_name.to_sym
|
20
|
+
mod.const_get(class_name)
|
21
|
+
else
|
22
|
+
container_parts.pop
|
23
|
+
class_from_string(class_name, container_parts.join('::'))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :class_names, :default
|
29
|
+
|
30
|
+
def initialize(class_names, default: ActiveFedora::Base)
|
31
|
+
@class_names = Array(class_names)
|
32
|
+
@default = default
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Convert all the provided class names to class instances
|
37
|
+
def models
|
38
|
+
class_names.map do |uri|
|
39
|
+
classify(uri)
|
40
|
+
end.compact
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Select the "best" class from the list of class names. We define
|
45
|
+
# the "best" class as:
|
46
|
+
# - a subclass of the given default, base class
|
47
|
+
# - preferring subclasses over the parent class
|
48
|
+
def best_model(opts = {})
|
49
|
+
best_model_match = opts.fetch(:default, default)
|
50
|
+
|
51
|
+
models.each do |model_value|
|
52
|
+
# If there is an inheritance structure, use the most specific case.
|
53
|
+
best_model_match = model_value if best_model_match.nil? || best_model_match > model_value
|
54
|
+
end
|
55
|
+
|
56
|
+
best_model_match
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def classify(model_value)
|
62
|
+
unless class_exists?(model_value)
|
63
|
+
ActiveFedora::Base.logger.warn "'#{model_value}' is not a real class" if ActiveFedora::Base.logger
|
64
|
+
return nil
|
65
|
+
end
|
66
|
+
ActiveFedora::ModelClassifier.class_from_string(model_value)
|
67
|
+
end
|
68
|
+
|
69
|
+
def class_exists?(class_name)
|
70
|
+
return false if class_name.empty?
|
71
|
+
klass = class_name.constantize
|
72
|
+
return klass.is_a?(Class)
|
73
|
+
rescue NameError
|
74
|
+
return false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -60,9 +60,9 @@ module ActiveFedora
|
|
60
60
|
options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
|
61
61
|
|
62
62
|
attr_names.each do |association_name|
|
63
|
-
if reflection =
|
64
|
-
reflection.
|
65
|
-
|
63
|
+
if reflection = _reflect_on_association(association_name)
|
64
|
+
reflection.autosave = true
|
65
|
+
define_autosave_association_callbacks(reflection)
|
66
66
|
## TODO this ought to work, but doesn't seem to do the class inheritance right
|
67
67
|
|
68
68
|
nested_attributes_options = self.nested_attributes_options.dup
|
@@ -70,10 +70,8 @@ module ActiveFedora
|
|
70
70
|
self.nested_attributes_options = nested_attributes_options
|
71
71
|
|
72
72
|
type = (reflection.collection? ? :collection : :one_to_one)
|
73
|
+
generate_association_writer(association_name, type)
|
73
74
|
|
74
|
-
# def pirate_attributes=(attributes)
|
75
|
-
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
|
76
|
-
# end
|
77
75
|
class_eval <<-eoruby, __FILE__, __LINE__ + 1
|
78
76
|
remove_possible_method(:#{association_name}_attributes=)
|
79
77
|
|
@@ -83,6 +81,7 @@ module ActiveFedora
|
|
83
81
|
eoruby
|
84
82
|
elsif reflect_on_property(association_name)
|
85
83
|
resource_class.accepts_nested_attributes_for(association_name, options)
|
84
|
+
generate_property_writer(association_name, type)
|
86
85
|
|
87
86
|
# Delegate the setter to the resource.
|
88
87
|
class_eval <<-eoruby, __FILE__, __LINE__ + 1
|
@@ -98,6 +97,53 @@ module ActiveFedora
|
|
98
97
|
end
|
99
98
|
end
|
100
99
|
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
# Generates a writer method for this association. Serves as a point for
|
104
|
+
# accessing the objects in the association. For example, this method
|
105
|
+
# could generate the following:
|
106
|
+
#
|
107
|
+
# def pirate_attributes=(attributes)
|
108
|
+
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
|
109
|
+
# end
|
110
|
+
#
|
111
|
+
# This redirects the attempts to write objects in an association through
|
112
|
+
# the helper methods defined below. Makes it seem like the nested
|
113
|
+
# associations are just regular associations.
|
114
|
+
def generate_association_writer(association_name, type)
|
115
|
+
generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
|
116
|
+
if method_defined?(:#{association_name}_attributes=)
|
117
|
+
remove_method(:#{association_name}_attributes=)
|
118
|
+
end
|
119
|
+
def #{association_name}_attributes=(attributes)
|
120
|
+
assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
|
121
|
+
end
|
122
|
+
eoruby
|
123
|
+
end
|
124
|
+
|
125
|
+
# Generates a writer method for this association. Serves as a point for
|
126
|
+
# accessing the objects in the association. For example, this method
|
127
|
+
# could generate the following:
|
128
|
+
#
|
129
|
+
# def pirate_attributes=(attributes)
|
130
|
+
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes)
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# This redirects the attempts to write objects in an association through
|
134
|
+
# the helper methods defined below. Makes it seem like the nested
|
135
|
+
# associations are just regular associations.
|
136
|
+
def generate_property_writer(association_name, _type)
|
137
|
+
generated_association_methods.module_eval <<-eoruby, __FILE__, __LINE__ + 1
|
138
|
+
if method_defined?(:#{association_name}_attributes=)
|
139
|
+
remove_method(:#{association_name}_attributes=)
|
140
|
+
end
|
141
|
+
def #{association_name}_attributes=(attributes)
|
142
|
+
attribute_will_change!(:#{association_name})
|
143
|
+
resource.#{association_name}_attributes=(attributes)
|
144
|
+
end
|
145
|
+
eoruby
|
146
|
+
end
|
101
147
|
end
|
102
148
|
|
103
149
|
# Returns ActiveFedora::Base#marked_for_destruction? It's
|
@@ -115,13 +161,63 @@ module ActiveFedora
|
|
115
161
|
# These hash keys are nested attributes implementation details.
|
116
162
|
UNASSIGNABLE_KEYS = %w( id _destroy ).freeze
|
117
163
|
|
164
|
+
# Assigns the given attributes to the association.
|
165
|
+
#
|
166
|
+
# If an associated record does not yet exist, one will be instantiated. If
|
167
|
+
# an associated record already exists, the method's behavior depends on
|
168
|
+
# the value of the update_only option. If update_only is +false+ and the
|
169
|
+
# given attributes include an <tt>:id</tt> that matches the existing record's
|
170
|
+
# id, then the existing record will be modified. If no <tt>:id</tt> is provided
|
171
|
+
# it will be replaced with a new record. If update_only is +true+ the existing
|
172
|
+
# record will be modified regardless of whether an <tt>:id</tt> is provided.
|
173
|
+
#
|
174
|
+
# If the given attributes include a matching <tt>:id</tt> attribute, or
|
175
|
+
# update_only is true, and a <tt>:_destroy</tt> key set to a truthy value,
|
176
|
+
# then the existing record will be marked for destruction.
|
177
|
+
def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
|
178
|
+
options = nested_attributes_options[association_name]
|
179
|
+
|
180
|
+
attributes = attributes.to_h if attributes.respond_to?(:permitted?)
|
181
|
+
attributes = attributes.with_indifferent_access
|
182
|
+
existing_record = send(association_name)
|
183
|
+
|
184
|
+
if (options[:update_only] || !attributes['id'].blank?) && existing_record &&
|
185
|
+
(options[:update_only] || existing_record.id.to_s == attributes['id'].to_s)
|
186
|
+
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy]) unless call_reject_if(association_name, attributes)
|
187
|
+
|
188
|
+
elsif attributes['id'].present?
|
189
|
+
raise_nested_attributes_record_not_found!(association_name, attributes['id'])
|
190
|
+
|
191
|
+
elsif !reject_new_record?(association_name, attributes)
|
192
|
+
assignable_attributes = attributes.except(*UNASSIGNABLE_KEYS)
|
193
|
+
|
194
|
+
if existing_record && existing_record.new_record?
|
195
|
+
existing_record.assign_attributes(assignable_attributes)
|
196
|
+
association(association_name).initialize_attributes(existing_record)
|
197
|
+
else
|
198
|
+
method = "build_#{association_name}"
|
199
|
+
if respond_to?(method)
|
200
|
+
send(method, assignable_attributes)
|
201
|
+
else
|
202
|
+
raise ArgumentError, "Cannot build association `#{association_name}'. Are you trying to build a polymorphic one-to-one association?"
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
118
208
|
def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
|
119
209
|
options = nested_attributes_options[association_name]
|
120
210
|
|
121
|
-
if
|
122
|
-
|
211
|
+
if attributes_collection.respond_to?(:permitted?)
|
212
|
+
attributes_collection = attributes_collection.to_h
|
123
213
|
end
|
124
214
|
|
215
|
+
unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
|
216
|
+
raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
|
217
|
+
end
|
218
|
+
|
219
|
+
check_record_limit!(options[:limit], attributes_collection)
|
220
|
+
|
125
221
|
if attributes_collection.is_a? Hash
|
126
222
|
keys = attributes_collection.keys
|
127
223
|
attributes_collection = if keys.include?('id') || keys.include?(:id)
|
@@ -134,13 +230,14 @@ module ActiveFedora
|
|
134
230
|
association = send(association_name)
|
135
231
|
|
136
232
|
existing_records = if association.loaded?
|
137
|
-
association.
|
233
|
+
association.target
|
138
234
|
else
|
139
235
|
attribute_ids = attributes_collection.map { |a| a['id'] || a[:id] }.compact
|
140
236
|
attribute_ids.present? ? association.to_a.select { |x| attribute_ids.include?(x.id) } : []
|
141
237
|
end
|
142
238
|
|
143
239
|
attributes_collection.each do |attributes|
|
240
|
+
attributes = attributes.to_h if attributes.respond_to?(:permitted)
|
144
241
|
attributes = attributes.with_indifferent_access
|
145
242
|
|
146
243
|
if attributes['id'].blank?
|
@@ -156,11 +253,31 @@ module ActiveFedora
|
|
156
253
|
end
|
157
254
|
|
158
255
|
else
|
159
|
-
raise_nested_attributes_record_not_found(association_name, attributes['id'])
|
256
|
+
raise_nested_attributes_record_not_found!(association_name, attributes['id'])
|
160
257
|
end
|
161
258
|
end
|
162
259
|
end
|
163
260
|
|
261
|
+
# Takes in a limit and checks if the attributes_collection has too many
|
262
|
+
# records. It accepts limit in the form of symbol, proc, or
|
263
|
+
# number-like object (anything that can be compared with an integer).
|
264
|
+
#
|
265
|
+
# Raises TooManyRecords error if the attributes_collection is
|
266
|
+
# larger than the limit.
|
267
|
+
def check_record_limit!(limit, attributes_collection)
|
268
|
+
return unless limit
|
269
|
+
limit = case limit
|
270
|
+
when Symbol
|
271
|
+
send(limit)
|
272
|
+
when Proc
|
273
|
+
limit.call
|
274
|
+
else
|
275
|
+
limit
|
276
|
+
end
|
277
|
+
|
278
|
+
raise TooManyRecords, "Maximum #{limit} records are allowed. Got #{attributes_collection.size} records instead." if limit && attributes_collection.size > limit
|
279
|
+
end
|
280
|
+
|
164
281
|
# Updates a record with the +attributes+ or marks it for destruction if
|
165
282
|
# +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
|
166
283
|
def assign_to_or_mark_for_destruction(record, attributes, allow_destroy)
|
@@ -170,19 +287,14 @@ module ActiveFedora
|
|
170
287
|
|
171
288
|
# Determines if a hash contains a truthy _destroy key.
|
172
289
|
def has_destroy_flag?(hash)
|
173
|
-
|
290
|
+
Type::Boolean.new.cast(hash['_destroy'])
|
174
291
|
end
|
175
292
|
|
176
293
|
# Determines if a new record should be rejected by checking
|
177
294
|
# has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
|
178
295
|
# association and evaluates to +true+.
|
179
296
|
def reject_new_record?(association_name, attributes)
|
180
|
-
|
181
|
-
end
|
182
|
-
|
183
|
-
def raise_nested_attributes_record_not_found(association_name, record_id)
|
184
|
-
reflection = self.class.reflect_on_association(association_name)
|
185
|
-
raise ObjectNotFoundError, "Couldn't find #{reflection.klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
|
297
|
+
will_be_destroyed?(association_name, attributes) || call_reject_if(association_name, attributes)
|
186
298
|
end
|
187
299
|
|
188
300
|
# Determines if a record with the particular +attributes+ should be
|
@@ -191,8 +303,9 @@ module ActiveFedora
|
|
191
303
|
#
|
192
304
|
# Returns false if there is a +destroy_flag+ on the attributes.
|
193
305
|
def call_reject_if(association_name, attributes)
|
306
|
+
return false if will_be_destroyed?(association_name, attributes)
|
307
|
+
|
194
308
|
opts = nested_attributes_options[association_name]
|
195
|
-
return false if has_destroy_flag?(attributes) && opts[:allow_destroy]
|
196
309
|
case callback = opts[:reject_if]
|
197
310
|
when Symbol
|
198
311
|
method(callback).arity == 0 ? send(callback) : send(callback, attributes)
|
@@ -200,5 +313,19 @@ module ActiveFedora
|
|
200
313
|
callback.call(attributes)
|
201
314
|
end
|
202
315
|
end
|
316
|
+
|
317
|
+
# Only take into account the destroy flag if <tt>:allow_destroy</tt> is true
|
318
|
+
def will_be_destroyed?(association_name, attributes)
|
319
|
+
allow_destroy?(association_name) && has_destroy_flag?(attributes)
|
320
|
+
end
|
321
|
+
|
322
|
+
def allow_destroy?(association_name)
|
323
|
+
nested_attributes_options[association_name][:allow_destroy]
|
324
|
+
end
|
325
|
+
|
326
|
+
def raise_nested_attributes_record_not_found!(association_name, record_id)
|
327
|
+
reflection = self.class._reflect_on_association(association_name).klass.name
|
328
|
+
raise ObjectNotFoundError, "Couldn't find #{reflection.klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
|
329
|
+
end
|
203
330
|
end
|
204
331
|
end
|
@@ -57,7 +57,7 @@ module ActiveFedora
|
|
57
57
|
raise ObjectNotFoundError, "Unable to find #{id} in the repository"
|
58
58
|
end
|
59
59
|
|
60
|
-
ActiveFedora::SolrService.delete(id) if
|
60
|
+
ActiveFedora::SolrService.delete(id) if ActiveFedora.enable_solr_updates?
|
61
61
|
self.class.eradicate(id) if opts[:eradicate]
|
62
62
|
freeze
|
63
63
|
end
|
@@ -14,6 +14,7 @@ module ActiveFedora
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.find_graph_predicate(predicate)
|
17
|
+
Deprecation.warn("find_graph_predicate has been deprecated and will be removed in ActiveFedora 10.0")
|
17
18
|
# TODO, these could be cached
|
18
19
|
case predicate
|
19
20
|
when :has_model, "hasModel", :hasModel
|
@@ -42,6 +43,7 @@ module ActiveFedora
|
|
42
43
|
end
|
43
44
|
|
44
45
|
def self.vocabularies(vocabs = {})
|
46
|
+
Deprecation.warn("vocabularies has been deprecated and will be removed in ActiveFedora 10.0")
|
45
47
|
@vocabularies ||= vocabs
|
46
48
|
predicate_mappings.keys.each do |ns|
|
47
49
|
@vocabularies[ns] = ::RDF::Vocabulary.new(ns) unless @vocabularies.key? ns
|
@@ -75,6 +77,7 @@ module ActiveFedora
|
|
75
77
|
end
|
76
78
|
|
77
79
|
def self.predicate_namespaces
|
80
|
+
Deprecation.warn("predicate_namespaces has been deprecated and will be removed in ActiveFedora 10.0")
|
78
81
|
predicate_config[:predicate_namespaces] ||= {}
|
79
82
|
end
|
80
83
|
|
@@ -147,7 +147,7 @@ module ActiveFedora
|
|
147
147
|
@fields.each do |field_key, field_info|
|
148
148
|
things = send(field_key)
|
149
149
|
next unless things
|
150
|
-
field_symbol = ActiveFedora
|
150
|
+
field_symbol = ActiveFedora.index_field_mapper.solr_name(field_key, type: field_info[:type])
|
151
151
|
things.val.each do |val|
|
152
152
|
::Solrizer::Extractor.insert_solr_field_value(solr_doc, field_symbol, val)
|
153
153
|
end
|