active-fedora 9.10.0.pre2 → 9.10.0

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/History.txt +141 -0
  4. data/lib/active_fedora/associations/association.rb +38 -12
  5. data/lib/active_fedora/associations/association_scope.rb +6 -2
  6. data/lib/active_fedora/associations/basic_contains_association.rb +2 -3
  7. data/lib/active_fedora/associations/belongs_to_association.rb +23 -4
  8. data/lib/active_fedora/associations/builder/association.rb +37 -56
  9. data/lib/active_fedora/associations/builder/belongs_to.rb +27 -1
  10. data/lib/active_fedora/associations/builder/collection_association.rb +33 -2
  11. data/lib/active_fedora/associations/builder/contains.rb +3 -3
  12. data/lib/active_fedora/associations/builder/directly_contains.rb +1 -7
  13. data/lib/active_fedora/associations/builder/directly_contains_one.rb +20 -17
  14. data/lib/active_fedora/associations/builder/has_and_belongs_to_many.rb +1 -1
  15. data/lib/active_fedora/associations/builder/has_many.rb +2 -43
  16. data/lib/active_fedora/associations/builder/indirectly_contains.rb +1 -7
  17. data/lib/active_fedora/associations/builder/property.rb +2 -13
  18. data/lib/active_fedora/associations/builder/singular_association.rb +2 -6
  19. data/lib/active_fedora/associations/builder/singular_property.rb +2 -3
  20. data/lib/active_fedora/associations/collection_association.rb +6 -14
  21. data/lib/active_fedora/associations/directly_contains_one_association.rb +1 -2
  22. data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +1 -1
  23. data/lib/active_fedora/associations/has_many_association.rb +23 -0
  24. data/lib/active_fedora/attached_files.rb +1 -1
  25. data/lib/active_fedora/core.rb +2 -1
  26. data/lib/active_fedora/errors.rb +13 -0
  27. data/lib/active_fedora/file.rb +16 -1
  28. data/lib/active_fedora/file/attributes.rb +6 -6
  29. data/lib/active_fedora/reflection.rb +200 -76
  30. data/lib/active_fedora/version.rb +1 -1
  31. data/lib/active_fedora/with_metadata/metadata_node.rb +2 -1
  32. data/lib/generators/active_fedora/config/fedora/fedora_generator.rb +4 -0
  33. data/lib/generators/active_fedora/config/fedora/templates/.fcrepo_wrapper +3 -0
  34. data/lib/generators/active_fedora/config/solr/solr_generator.rb +4 -0
  35. data/lib/generators/active_fedora/config/solr/templates/.solr_wrapper +5 -0
  36. data/spec/integration/attached_files_spec.rb +4 -4
  37. data/spec/integration/file_spec.rb +1 -1
  38. data/spec/integration/om_datastream_spec.rb +6 -6
  39. data/spec/unit/collection_proxy_spec.rb +1 -1
  40. data/spec/unit/file_spec.rb +19 -0
  41. data/spec/unit/has_and_belongs_to_many_association_spec.rb +4 -4
  42. data/spec/unit/has_many_association_spec.rb +2 -2
  43. data/spec/unit/reflection_spec.rb +2 -2
  44. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9fa729bb22950bf6f1a5a8910eef83e17d699b6
4
- data.tar.gz: 2230ceaf9cf100c0737997c5235c0a87364ec2df
3
+ metadata.gz: 8497f7de37069e9bfe075f4b7f9ac67a0e3c7d68
4
+ data.tar.gz: cb858eb8a45c08fec2dea7578b854cc51b4b5401
5
5
  SHA512:
6
- metadata.gz: df06b4f7448346189c3ca49029200205eaf671a84854035fba131dc60d84f0954aaf79df54e29746118cac1074ca2241e7b5bc7e291f89b120e44340b034d250
7
- data.tar.gz: 60a819b84ffd5f68bdb80436648621738e2b77b68e629265be3d3257efa566969d33c040660a561445c39a60d38742865afd0dd6b6681ef0aeb7bfc8cd08d961
6
+ metadata.gz: 6307a89a0b6417ef313efda00a37466cd0ef1f8a9bbb18dafb5f7fbbedc7dd87598f3213619604e6dac06f55eb985dc87c0b99b3f3e33369d213e038bbf56f02
7
+ data.tar.gz: d084f99333f8059f504b6735fde1bab7ace4868de441b2f48ced69d876a7271570007c9452acb4f10f22f05e39efa513130eb09562d1a8ad8d2151fbe7d60a0d
@@ -86,6 +86,7 @@ Metrics/ClassLength:
86
86
  - 'lib/active_fedora/associations/builder/association.rb'
87
87
  - 'lib/active_fedora/associations/collection_proxy.rb'
88
88
  - 'lib/active_fedora/associations/collection_association.rb'
89
+ - 'lib/active_fedora/reflection.rb'
89
90
 
90
91
  Metrics/MethodLength:
91
92
  Enabled: false
@@ -1,3 +1,144 @@
1
+ v9.10.0
2
+ 2016-03-24: Continued alignment of associations with upstream changes [Chris
3
+ Beer]
4
+
5
+ 2016-03-24: ActiveFedora::File.mime_type should be updatable [Chris Colvard]
6
+
7
+ 2016-03-23: Update reflections and associations to reflect upstream changes
8
+ [Chris Beer]
9
+
10
+ 2016-03-23: Generate default configs for fcrepo_wrapper [Justin Coyne]
11
+
12
+ 2016-03-23: Generate solr_wrapper config file [Justin Coyne]
13
+
14
+ 2016-03-22: Bump version to 9.10.0.pre2 [Justin Coyne]
15
+
16
+ 2016-03-19: Update scoping with latest upstream changes [Chris Beer]
17
+
18
+ 2016-03-22: Deprecate delegating attributes to associated objects [Justin Coyne]
19
+
20
+ 2016-03-22: Add AttributeAssignment module from upstream [Chris Beer]
21
+
22
+ 2016-03-21: Update AF::AttributeMethods with upstream changes [Chris Beer]
23
+
24
+ 2016-03-21: Extract ActiveFedora::Common to share methods between AF::Base and
25
+ AF::File [Chris Beer]
26
+
27
+ 2016-03-18: Update AF::File update callbacks to align with Rails [Chris Beer]
28
+
29
+ 2016-03-18: Extract ActiveFedora::FilePersistence, so ActiveFedora::File can
30
+ work with AF::Callbacks [Chris Beer]
31
+
32
+ 2016-03-18: Prefix internal create_ and update_record callbacks with an
33
+ underscore [Chris Beer]
34
+
35
+ 2016-03-18: Add create_or_update to provide save callbacks [Chris Beer]
36
+
37
+ 2016-03-18: Add ActiveFedora::Persistence#destroy! [Chris Beer]
38
+
39
+ 2016-03-20: Correctly find the size of a collection in memory [Justin Coyne]
40
+
41
+ 2016-03-18: Bump version to 9.10.0.pre1 [Justin Coyne]
42
+
43
+ 2016-03-18: Update Validations with latest upstream changes [Chris Beer]
44
+
45
+ 2016-03-18: Delegate count to the scope [Justin Coyne]
46
+
47
+ 2016-03-18: Update nested attributes with upstream improvements [Chris Beer]
48
+
49
+ 2016-03-18: Update reflection methods to match new upstream names [Chris Beer]
50
+
51
+ 2016-03-18: Add explicit ActiveModel dependency [Chris Beer]
52
+
53
+ 2016-03-18: Update minimum versions of ruby and activesupport [Chris Beer]
54
+
55
+ 2016-03-17: Extract Builder::Association.create_reflection [Chris Beer]
56
+
57
+ 2016-03-17: Delegate responsibility for cleaning up dependencies to association
58
+ instances [Chris Beer]
59
+
60
+ 2016-03-17: validate dependent options [Chris Beer]
61
+
62
+ 2016-03-17: Port .dangerous_attribute_method? from Rails [Chris Beer]
63
+
64
+ 2016-03-17: Migrate valid_options from a class attribute to a method [Chris
65
+ Beer]
66
+
67
+ 2016-03-17: Convert Assocations::Builder.macro from a class variable to a class
68
+ method [Chris Beer]
69
+
70
+ 2016-03-15: Add default scopes [Justin Coyne]
71
+
72
+ 2016-03-16: Unconditionally run coverage reports when running tests [Chris Beer]
73
+
74
+ 2016-03-16: Remove or deprecate unused code [Chris Beer]
75
+
76
+ 2016-03-16: Silence SolrQueryBuilder deprecation warnings when running tests
77
+ [Chris Beer]
78
+
79
+ 2016-03-16: Update relation calculations to use SolrService.count [Chris Beer]
80
+
81
+ 2016-03-16: Extract SolrService.get to send requests to Solr and get the
82
+ original response [Chris Beer]
83
+
84
+ 2016-03-16: Use field queries instead of raw queries [Chris Beer]
85
+
86
+ 2016-03-16: Deprecate ActiveFedora::SolrQueryBuilder.raw_query in favor of
87
+ .construct_query [Chris Beer]
88
+
89
+ 2016-03-16: Deprecate ActiveFedora::SolrQueryBuilder.solr_name in favor of using
90
+ ActiveFedora.index_field_mapper directly [Chris Beer]
91
+
92
+ 2016-03-15: Extract SolrHit class to wrap Solr response documents [Chris Beer]
93
+
94
+ 2016-03-15: Deprecate unused methods [Justin Coyne]
95
+
96
+ 2016-03-15: ActiveFedora depends on Solrizer [Justin Coyne]
97
+
98
+ 2016-03-15: Don't rely on exceptions for flow control [Justin Coyne]
99
+
100
+ 2016-03-15: Update testing versions of Ruby and Rails [Justin Coyne]
101
+
102
+ 2016-03-15: Push .search_by_id into ActiveFedora::FinderMethod [Chris Beer]
103
+
104
+ 2016-03-15: Rename find_with_conditions and find_in_batches to
105
+ search_with_conditions and search_in_batches [Chris Beer]
106
+
107
+ 2016-03-11: Provide class-level accessors in place of global constants for
108
+ configuration [Chris Beer]
109
+
110
+ 2016-03-11: Use ActiveFedora.index_field_mapper instead of accessing Solrizer
111
+ directly [Chris Beer]
112
+
113
+ 2016-03-11: Use the same logic for lazy_reify_solr_results and
114
+ reify_solr_results [Chris Beer]
115
+
116
+ 2016-03-10: Move indexer to a class attribute [Justin Coyne]
117
+
118
+ 2016-03-09: Decompose ActiveFedora::Model into a generic model mapper and a
119
+ classifier [Chris Beer]
120
+
121
+ 2016-03-09: Add DefaultModelMapper class to encapsulate model selection logic
122
+ [Chris Beer]
123
+
124
+ 2016-03-09: Use ActiveFedora.model_mapper accessor to get the type to class
125
+ mapper [Chris Beer]
126
+
127
+ 2016-03-09: Unify class lookup for Fedora types to ActiveFedora models [Chris
128
+ Beer]
129
+
130
+ 2016-03-09: Move ActiveFedora.class_from_string into ActiveFedora::Model [Chris
131
+ Beer]
132
+
133
+ 2016-03-09: Remove require of rubocop-rspec [Justin Coyne]
134
+
135
+ 2016-03-09: Pin rake to ~> 10.0 [Justin Coyne]
136
+
137
+ 2016-03-09: Update test to support ActiveModel 4.2.6 [Justin Coyne]
138
+
139
+ 2016-03-08: Update to use ldp 0.5 [Chris Beer]
140
+
141
+
1
142
  v9.9.1
2
143
  2016-03-05: Restore autocommit in the update handler [Justin Coyne]
3
144
 
@@ -76,7 +76,7 @@ module ActiveFedora
76
76
  # by scope.scoping { ... } or with_scope { ... } etc, which affects the scope which
77
77
  # actually gets built.
78
78
  def association_scope
79
- @association_scope ||= AssociationScope.new(self).scope if klass
79
+ @association_scope ||= AssociationScope.scope(self) if klass
80
80
  end
81
81
 
82
82
  def reset_scope
@@ -115,12 +115,17 @@ module ActiveFedora
115
115
  @target = find_target if (@stale_state && stale_target?) || find_target?
116
116
  loaded! unless loaded?
117
117
  target
118
+ rescue ActiveFedora::ObjectNotFoundError
119
+ reset
118
120
  end
119
121
 
120
- def initialize_attributes(record) #:nodoc:
122
+ def initialize_attributes(record, except_from_scope_attributes = nil) #:nodoc:
123
+ except_from_scope_attributes ||= {}
121
124
  skip_assign = [reflection.foreign_key].compact
122
- attributes = create_scope.except(*(record.changed - skip_assign))
123
- record.attributes = attributes
125
+ assigned_keys = record.changed
126
+ assigned_keys += except_from_scope_attributes.keys.map(&:to_s)
127
+ attributes = create_scope.except(*(assigned_keys - skip_assign))
128
+ record.assign_attributes(attributes)
124
129
  set_inverse_instance(record)
125
130
  end
126
131
 
@@ -130,6 +135,25 @@ module ActiveFedora
130
135
  !loaded? && (!owner.new_record? || foreign_key_present?) && klass
131
136
  end
132
137
 
138
+ def creation_attributes
139
+ attributes = {}
140
+
141
+ if (reflection.has_one? || reflection.collection?) && !options[:through]
142
+ attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
143
+
144
+ if reflection.options[:as]
145
+ attributes[reflection.type] = owner.class.base_class.name
146
+ end
147
+ end
148
+
149
+ attributes
150
+ end
151
+
152
+ # Sets the owner attributes on the given record
153
+ def set_owner_attributes(record)
154
+ creation_attributes.each { |key, value| record[key] = value }
155
+ end
156
+
133
157
  # Returns true if there is a foreign key present on the owner which
134
158
  # references the target. This is used to determine whether we can load
135
159
  # the target if the owner is currently a new record (and therefore
@@ -144,10 +168,16 @@ module ActiveFedora
144
168
  # Raises ActiveFedora::AssociationTypeMismatch unless +record+ is of
145
169
  # the kind of the class of the associated objects. Meant to be used as
146
170
  # a sanity check when you are about to assign an associated record.
147
- def raise_on_type_mismatch(record)
148
- return if record.is_a?(@reflection.klass) || record.is_a?(@reflection.class_name.constantize)
149
- message = "#{@reflection.class_name}(##{@reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
150
- raise ActiveFedora::AssociationTypeMismatch, message
171
+ def raise_on_type_mismatch!(record)
172
+ unless record.is_a?(reflection.klass)
173
+ fresh_class = reflection.class_name.safe_constantize
174
+ unless fresh_class && record.is_a?(fresh_class)
175
+ message = "#{reflection.class_name}(##{reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
176
+ raise ActiveFedora::AssociationTypeMismatch, message
177
+ end
178
+ end
179
+
180
+ type_validator.validate!(self, record)
151
181
  end
152
182
 
153
183
  def type_validator
@@ -180,10 +210,6 @@ module ActiveFedora
180
210
  initialize_attributes(record)
181
211
  end
182
212
  end
183
-
184
- def run_type_validator(record)
185
- type_validator.validate!(self, record)
186
- end
187
213
  end
188
214
  end
189
215
  end
@@ -1,6 +1,10 @@
1
1
  module ActiveFedora
2
2
  module Associations
3
3
  class AssociationScope #:nodoc:
4
+ def self.scope(association)
5
+ new(association).scope
6
+ end
7
+
4
8
  attr_reader :association
5
9
 
6
10
  delegate :klass, :owner, :reflection, :interpolate, to: :association
@@ -19,10 +23,10 @@ module ActiveFedora
19
23
 
20
24
  def add_constraints(scope)
21
25
  chain.each_with_index do |reflection, i|
22
- if reflection.source_macro == :belongs_to
26
+ if reflection.macro == :belongs_to
23
27
  # Create a partial solr query using the ids. We may add additional filters such as class_name later
24
28
  scope = scope.where(ActiveFedora::SolrQueryBuilder.construct_query_for_ids([owner[reflection.foreign_key]]))
25
- elsif reflection.source_macro == :has_and_belongs_to_many
29
+ elsif reflection.macro == :has_and_belongs_to_many
26
30
  else
27
31
  scope = scope.where(ActiveFedora::SolrQueryBuilder.construct_query_for_rel(association.send(:find_reflection) => owner.id))
28
32
  end
@@ -18,7 +18,7 @@ module ActiveFedora
18
18
 
19
19
  private
20
20
 
21
- def raise_on_type_mismatch(record)
21
+ def raise_on_type_mismatch!(record)
22
22
  return if record.is_a? LoadableFromJson::SolrBackedMetadataFile
23
23
  super
24
24
  end
@@ -35,8 +35,7 @@ module ActiveFedora
35
35
 
36
36
  def replace(record)
37
37
  if record
38
- raise_on_type_mismatch(record)
39
- run_type_validator(record)
38
+ raise_on_type_mismatch!(record)
40
39
  @updated = true
41
40
  end
42
41
 
@@ -1,16 +1,19 @@
1
1
  module ActiveFedora
2
2
  module Associations
3
3
  class BelongsToAssociation < SingularAssociation #:nodoc:
4
+ def handle_dependency
5
+ target.send(options[:dependent]) if load_target
6
+ end
7
+
4
8
  def replace(record)
5
9
  if record
6
- raise_on_type_mismatch(record)
7
- run_type_validator(record)
8
- # update_counters(record)
10
+ raise_on_type_mismatch!(record)
11
+ update_counters_on_replace(record)
9
12
  replace_keys(record)
10
13
  set_inverse_instance(record)
11
14
  @updated = true
12
15
  else
13
- # decrement_counters
16
+ decrement_counters
14
17
  remove_keys
15
18
  end
16
19
 
@@ -26,8 +29,24 @@ module ActiveFedora
26
29
  @updated
27
30
  end
28
31
 
32
+ def decrement_counters # :nodoc:
33
+ # noop
34
+ end
35
+
36
+ def increment_counters # :nodoc:
37
+ # noop
38
+ end
39
+
29
40
  private
30
41
 
42
+ def find_target?
43
+ !loaded? && foreign_key_present? && klass
44
+ end
45
+
46
+ def update_counters_on_replace(_record)
47
+ # noop
48
+ end
49
+
31
50
  def replace_keys(record)
32
51
  owner[reflection.foreign_key] = record.id
33
52
  end
@@ -7,20 +7,6 @@ module ActiveFedora::Associations::Builder
7
7
 
8
8
  VALID_OPTIONS = [:class_name, :predicate, :type_validator].freeze
9
9
 
10
- def self.macro
11
- raise NotImplementedError
12
- end
13
-
14
- def self.valid_options(_options)
15
- VALID_OPTIONS + Association.extensions.flat_map(&:valid_options)
16
- end
17
-
18
- def self.validate_options(options)
19
- options.assert_valid_keys(valid_options(options))
20
- end
21
-
22
- attr_reader :model, :name, :options, :mixin
23
-
24
10
  # configure_dependency
25
11
  def self.build(model, name, options, &block)
26
12
  if model.dangerous_attribute_method?(name)
@@ -37,42 +23,58 @@ module ActiveFedora::Associations::Builder
37
23
  reflection
38
24
  end
39
25
 
40
- def self.create_reflection(model, name, _scope, options, _extension = nil)
26
+ def self.create_reflection(model, name, scope, options, extension = nil)
41
27
  unless name.is_a?(Symbol)
42
28
  name = name.to_sym
43
29
  Deprecation.warn(ActiveFedora::Base, "association names must be a Symbol")
44
30
  end
45
-
46
31
  validate_options(options)
32
+ translate_property_to_predicate(options)
33
+
34
+ scope = build_scope(scope, extension)
35
+ name = better_name(name)
47
36
 
48
- new(model, name, options).build
37
+ ActiveFedora::Reflection.create(macro, name, scope, options, model)
49
38
  end
50
39
 
51
- def initialize(model, name, options)
52
- @model = model
53
- @name = name
54
- @options = options
55
- translate_property_to_predicate
56
- validate_options
40
+ def self.build_scope(scope, extension)
41
+ new_scope = scope
42
+
43
+ new_scope = proc { instance_exec(&scope) } if scope && scope.arity == 0
44
+
45
+ new_scope = wrap_scope new_scope, extension if extension
46
+
47
+ new_scope
57
48
  end
58
49
 
59
- def build
60
- configure_dependency if options[:dependent] # see https://github.com/rails/rails/commit/9da52a5e55cc665a539afb45783f84d9f3607282
61
- model.create_reflection(self.class.macro, name, options, model)
50
+ def self.wrap_scope(scope, _extension)
51
+ scope
62
52
  end
63
53
 
64
- def translate_property_to_predicate
54
+ def self.macro
55
+ raise NotImplementedError
56
+ end
57
+
58
+ def self.valid_options(_options)
59
+ VALID_OPTIONS + Association.extensions.flat_map(&:valid_options)
60
+ end
61
+
62
+ def self.validate_options(options)
63
+ options.assert_valid_keys(valid_options(options))
64
+ end
65
+
66
+ def self.better_name(name)
67
+ name
68
+ end
69
+
70
+ def self.translate_property_to_predicate(options)
65
71
  return unless options[:property]
66
72
  Deprecation.warn Association, "the :property option to `#{model}.#{macro} :#{name}' is deprecated and will be removed in active-fedora 10.0. Use :predicate instead", caller(5)
67
73
  options[:predicate] = predicate(options.delete(:property))
68
74
  end
69
75
 
70
- def validate_options
71
- self.class.validate_options(options)
72
- end
73
-
74
76
  # Returns the RDF predicate as defined by the :property attribute
75
- def predicate(property)
77
+ def self.predicate(property)
76
78
  return property if property.is_a? RDF::URI
77
79
  ActiveFedora::Predicates.find_graph_predicate(property)
78
80
  end
@@ -124,14 +126,6 @@ module ActiveFedora::Associations::Builder
124
126
  # noop
125
127
  end
126
128
 
127
- def self.add_destroy_callbacks(model, reflection)
128
- name = reflection.name
129
- model.before_destroy lambda do |o|
130
- a = o.association(name)
131
- a.handle_dependency if a.respond_to? :handle_dependency
132
- end
133
- end
134
-
135
129
  def self.valid_dependent_options
136
130
  raise NotImplementedError
137
131
  end
@@ -142,22 +136,9 @@ module ActiveFedora::Associations::Builder
142
136
  end
143
137
  end
144
138
 
145
- def configure_dependency
146
- return unless options[:dependent]
147
- return if model.association(name).respond_to? :handle_dependency
148
-
149
- unless [:destroy, :delete].include?(options[:dependent])
150
- raise ArgumentError, "The :dependent option expects either :destroy or :delete (#{options[:dependent].inspect})"
151
- end
152
-
153
- method_name = "belongs_to_dependent_#{options[:dependent]}_for_#{name}"
154
- model.send(:class_eval, <<-eoruby, __FILE__, __LINE__ + 1)
155
- def #{method_name}
156
- association = #{name}
157
- association.#{options[:dependent]} if association
158
- end
159
- eoruby
160
- model.after_destroy method_name
139
+ def self.add_destroy_callbacks(model, reflection)
140
+ name = reflection.name
141
+ model.before_destroy ->(o) { o.association(name).handle_dependency }
161
142
  end
162
143
  end
163
144
  end