active-fedora 9.4.1 → 9.4.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 855f69bd4803e18b9f69462e4661f4b1411c1997
4
- data.tar.gz: d81dd2a3c2bf2b447b2bf43215629f788ee50917
3
+ metadata.gz: 35b37e4ce4fb55f72c525f6868b769f60af55d98
4
+ data.tar.gz: 8705a17f008927df6c005fe327825c70479b1abe
5
5
  SHA512:
6
- metadata.gz: 8992f6b40ac67d48ac58126507cf5c71dc6fd6c62be916b3e62d4a40f8f0305905bef9a6cf123c891943faeb2f8b1ff7e5899bc2ada8c7cf6d9360db078ede53
7
- data.tar.gz: edfefa4d6ae6811c16bbe88267601d694077a9e9c4ca67f2ac4d3a45700a921cb18271129348e0ecb488245afe0649465c93d593eebf20263383265ea42ceb79
6
+ metadata.gz: 4a534d6c9f2710b9ec7f5802bff389f3fbe8d42152a15d9494eb1c1003acc92d66b9d6727cf2c56986b7ada339ef8e7b5871fe26dcd6fee1bd7b115aee0a58ee
7
+ data.tar.gz: 6ee26660bc33f7c8bd21f2c2618f3e0b3bc74355ae022b55bd201da6a85304509a577cd28710995442e78969251a7946ba2fdfd162b810330b5beacd398e3251
@@ -1,3 +1,18 @@
1
+ v9.4.2
2
+ 2015-09-25: Refactor nested_attribute test for easier reading [Justin Coyne]
3
+
4
+ 2015-09-25: Don't skip reject_if when _destroy is passed [Justin Coyne]
5
+
6
+ 2015-09-24: Don't use Fcrepo digest predicate from rdf-vocab [Justin Coyne]
7
+
8
+ 2015-09-24: Updating documentation of Indexing Service [Jeremy Friesen]
9
+
10
+ 2015-09-24: Moving a method to protected [Jeremy Friesen]
11
+
12
+ 2015-09-23: Add high-level comment for Indexing module. [Anna Headley]
13
+
14
+ 2015-09-18: Refactor nested_attribute_spec [Justin Coyne]
15
+
1
16
  v9.4.1
2
17
  2015-09-18: Update ldp gem to 0.4.0. [Justin Coyne]
3
18
 
@@ -17,7 +17,7 @@ module ActiveFedora::File::Attributes
17
17
  def digest
18
18
  response = metadata.ldp_source.graph.query(predicate: RDF::Vocab::PREMIS.hasMessageDigest)
19
19
  # fallback on old predicate for checksum
20
- response = metadata.ldp_source.graph.query(predicate: RDF::Vocab::Fcrepo4.digest) if response.empty?
20
+ response = metadata.ldp_source.graph.query(predicate: fallback_digest_predicate) if response.empty?
21
21
  response.map(&:object)
22
22
  end
23
23
 
@@ -43,6 +43,18 @@ module ActiveFedora::File::Attributes
43
43
 
44
44
  private
45
45
 
46
+ # Fcrepo4.digest was used by Fedora < 4.3, but it was removed
47
+ # from the 2015-07-24 version of the fedora 4 ontology
48
+ # http://fedora.info/definitions/v4/2015/07/24/repository and
49
+ # from rdf-vocab in version 0.8.5
50
+ def fallback_digest_predicate
51
+ @fallback_digest ||= if RDF::Vocab::Fcrepo4.respond_to? :digest
52
+ RDF::Vocab::Fcrepo4.digest
53
+ else
54
+ ::RDF::URI("http://fedora.info/definitions/v4/repository#digest")
55
+ end
56
+ end
57
+
46
58
  def links
47
59
  @links ||= Ldp::Response.links(ldp_source.head)
48
60
  end
@@ -18,11 +18,19 @@ module ActiveFedora
18
18
  end
19
19
 
20
20
  def status
21
- fixity_graph.query(predicate: ::RDF::Vocab::Fcrepo4.status).map(&:object).first.to_s
21
+ fixity_graph.query(predicate: status_predicate).map(&:object).first.to_s
22
22
  end
23
23
 
24
24
  private
25
25
 
26
+ # Fcrepo4.status was used by Fedora < 4.3, but it was removed
27
+ # from the 2015-07-24 version of the fedora 4 ontology
28
+ # http://fedora.info/definitions/v4/2015/07/24/repository and
29
+ # from rdf-vocab in version 0.8.5
30
+ def status_predicate
31
+ ::RDF::URI("http://fedora.info/definitions/v4/repository#status")
32
+ end
33
+
26
34
  def get_fixity_response_from_fedora
27
35
  uri = target + "/fcr:fixity"
28
36
  ActiveFedora.fedora.connection.get(encoded_url(uri))
@@ -1,4 +1,12 @@
1
1
  module ActiveFedora
2
+ # Mix in this module to update Solr on save.
3
+ # Assign a new indexer at the class level where this is mixed in
4
+ # (or define an #indexing_service method)
5
+ # to change the document contents sent to solr
6
+ #
7
+ # Example indexing services are:
8
+ # @see ActiveFedora::IndexingService
9
+ # @see ActiveFedora::RDF::IndexingService
2
10
  module Indexing
3
11
  extend ActiveSupport::Concern
4
12
  extend ActiveSupport::Autoload
@@ -10,7 +18,7 @@ module ActiveFedora
10
18
  # Return a Hash representation of this object where keys in the hash are appropriate Solr field names.
11
19
  # @param [Hash] solr_doc (optional) Hash to insert the fields into
12
20
  # @param [Hash] opts (optional)
13
- # If opts[:model_only] == true, the base object metadata and the RELS-EXT datastream will be omitted. This is mainly to support shelver, which calls .to_solr for each model an object subscribes to.
21
+ # If opts[:model_only] == true, the base object metadata and the RELS-EXT datastream will be omitted. This is mainly to support shelver, which calls #to_solr for each model an object subscribes to.
14
22
  def to_solr(solr_doc = Hash.new, opts={})
15
23
  indexing_service.generate_solr_document
16
24
  end
@@ -1,4 +1,9 @@
1
1
  module ActiveFedora
2
+ # Responsible for generating the solr document (via #generate_solr_document) of the
3
+ # given object.
4
+ #
5
+ # @see ActiveFedora::Indexing
6
+ # @see ActiveFedora::RDF::IndexingService
2
7
  class IndexingService
3
8
  attr_reader :object
4
9
 
@@ -14,10 +19,6 @@ module ActiveFedora
14
19
  @profile_solr_name ||= ActiveFedora::SolrQueryBuilder.solr_name("object_profile", :displayable)
15
20
  end
16
21
 
17
- def profile_service
18
- ProfileIndexingService
19
- end
20
-
21
22
  def rdf_service
22
23
  RDF::IndexingService
23
24
  end
@@ -43,6 +44,10 @@ module ActiveFedora
43
44
 
44
45
  protected
45
46
 
47
+ def profile_service
48
+ ProfileIndexingService
49
+ end
50
+
46
51
  def c_time
47
52
  c_time = object.create_date.present? ? object.create_date : DateTime.now
48
53
  c_time = DateTime.parse(c_time) unless c_time.is_a?(DateTime)
@@ -148,7 +148,9 @@ module ActiveFedora
148
148
  attributes = attributes.with_indifferent_access
149
149
 
150
150
  if attributes['id'].blank?
151
- association.build(attributes.except(*UNASSIGNABLE_KEYS)) unless call_reject_if(association_name, attributes)
151
+ unless reject_new_record?(association_name, attributes)
152
+ association.build(attributes.except(*UNASSIGNABLE_KEYS))
153
+ end
152
154
 
153
155
  elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes['id'].to_s }
154
156
  association.send(:add_record_to_target_with_callbacks, existing_record) if !association.loaded? && !call_reject_if(association_name, attributes)
@@ -176,22 +178,32 @@ module ActiveFedora
176
178
  ["1", "true"].include?(hash['_destroy'].to_s)
177
179
  end
178
180
 
181
+ # Determines if a new record should be rejected by checking
182
+ # has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
183
+ # association and evaluates to +true+.
184
+ def reject_new_record?(association_name, attributes)
185
+ has_destroy_flag?(attributes) || call_reject_if(association_name, attributes)
186
+ end
187
+
179
188
  def raise_nested_attributes_record_not_found(association_name, record_id)
180
189
  reflection = self.class.reflect_on_association(association_name)
181
190
  raise ObjectNotFoundError, "Couldn't find #{reflection.klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
182
191
  end
183
192
 
193
+ # Determines if a record with the particular +attributes+ should be
194
+ # rejected by calling the reject_if Symbol or Proc (if defined).
195
+ # The reject_if option is defined by +accepts_nested_attributes_for+.
196
+ #
197
+ # Returns false if there is a +destroy_flag+ on the attributes.
184
198
  def call_reject_if(association_name, attributes)
185
- return false if has_destroy_flag?(attributes)
186
- case callback = self.nested_attributes_options[association_name][:reject_if]
199
+ opts = self.nested_attributes_options[association_name]
200
+ return false if has_destroy_flag?(attributes) && opts[:allow_destroy]
201
+ case callback = opts[:reject_if]
187
202
  when Symbol
188
203
  method(callback).arity == 0 ? send(callback) : send(callback, attributes)
189
204
  when Proc
190
205
  callback.call(attributes)
191
206
  end
192
207
  end
193
-
194
208
  end
195
209
  end
196
-
197
-
@@ -1,4 +1,9 @@
1
1
  module ActiveFedora::RDF
2
+ # Responsible for generating the solr document (via #generate_solr_document) of the
3
+ # given object.
4
+ #
5
+ # @see ActiveFedora::Indexing
6
+ # @see ActiveFedora::IndexingService
2
7
  class IndexingService
3
8
  include Solrizer::Common
4
9
  attr_reader :object
@@ -70,7 +75,7 @@ module ActiveFedora::RDF
70
75
 
71
76
  # returns the field map instance
72
77
  def fields
73
- field_map_class.new do |field_map|
78
+ field_map_class.new do |field_map|
74
79
  index_config.each { |name, index_field_config| field_map.insert(name, index_field_config, object) }
75
80
  end
76
81
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "9.4.1"
2
+ VERSION = "9.4.2"
3
3
  end
@@ -4,128 +4,169 @@ describe "NestedAttribute behavior" do
4
4
  before do
5
5
  class Bar < ActiveFedora::Base
6
6
  belongs_to :car, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasMember
7
- has_metadata :type=>ActiveFedora::SimpleDatastream, :name=>"someData" do |m|
8
- m.field "uno", :string
9
- m.field "dos", :string
10
- end
11
- Deprecation.silence(ActiveFedora::Attributes) do
12
- has_attributes :uno, :dos, datastream: 'someData', multiple: false
13
- end
7
+ property :uno, predicate: ::RDF::URI('http://example.com/uno'), multiple: false
8
+ property :dos, predicate: ::RDF::URI('http://example.com/dos'), multiple: false
14
9
  end
15
10
 
16
11
  # base Car class, used in test for association updates and :allow_destroy flag
17
12
  class Car < ActiveFedora::Base
18
13
  has_many :bars, predicate: ActiveFedora::RDF::Fcrepo::RelsExt.hasMember
19
- accepts_nested_attributes_for :bars, :allow_destroy=>true
20
- end
21
-
22
- # class used in test for :reject_if=>:all_blank
23
- class CarAllBlank < Car
24
- accepts_nested_attributes_for :bars, :reject_if=>:all_blank
25
- end
26
-
27
- # class used in test for :reject_if with proc object
28
- class CarProc < Car
29
- accepts_nested_attributes_for :bars, :reject_if=>proc { |attributes| attributes['uno'].blank? }
30
- end
31
-
32
- # class used in test for :reject_if with method name as symbol
33
- class CarSymbol < Car
34
- accepts_nested_attributes_for :bars, :reject_if=>:uno_blank
35
-
36
- def uno_blank(attributes)
37
- attributes['uno'].blank?
38
- end
39
- end
40
-
41
- # class used in test for :limit
42
- class CarWithLimit < Car
43
- accepts_nested_attributes_for :bars, :limit => 1
14
+ accepts_nested_attributes_for :bars, allow_destroy: true
44
15
  end
45
16
  end
46
17
  after do
47
18
  Object.send(:remove_const, :Bar)
48
- Object.send(:remove_const, :CarAllBlank)
49
- Object.send(:remove_const, :CarProc)
50
- Object.send(:remove_const, :CarSymbol)
51
- Object.send(:remove_const, :CarWithLimit)
52
19
  Object.send(:remove_const, :Car)
53
20
  end
54
21
 
22
+ let(:car_class) { Car }
23
+ let(:car) { car_class.create }
24
+ let(:bar1) { Bar.create(car: car) }
25
+ let(:bar2) { Bar.create(car: car) }
26
+
27
+
55
28
  it "should have _destroy" do
56
29
  expect(Bar.new._destroy).to be_nil
57
30
  end
58
31
 
59
32
  it "should update the child objects" do
60
- @car, @bar1, @bar2 = create_car_with_bars
61
-
62
- @car.update bars_attributes: [{id: @bar1.id, uno: "bar1 uno"}, {uno: "newbar uno"}, {id: @bar2.id, _destroy: '1', uno: 'bar2 uno'}]
63
- expect(Bar.find(@bar1.id).uno).to eq 'bar1 uno'
64
- expect(Bar.where(:id => @bar2.id).first).to be_nil
65
- expect(Bar.where(:uno => "newbar uno").first).to_not be_nil
33
+ car.update bars_attributes: [{id: bar1.id, uno: "bar1 uno"}, {uno: "newbar uno"}, {id: bar2.id, _destroy: '1', uno: 'bar2 uno'}]
34
+ expect(Bar.all.map(&:uno)).to match_array ['bar1 uno', 'newbar uno']
66
35
 
67
- bars = @car.bars(true)
68
- expect(bars).to include(@bar1)
69
- expect(bars).to_not include(@bar2)
36
+ bars = car.bars(true)
37
+ expect(bars).to include(bar1)
38
+ expect(bars).to_not include(bar2)
70
39
  end
71
40
 
72
- it "should reject attributes when all blank" do
73
- @car, @bar1, @bar2 = create_car_with_bars(CarAllBlank)
41
+ context "when reject_if: :all_blank" do
42
+ before do
43
+ class CarAllBlank < Car
44
+ accepts_nested_attributes_for :bars, reject_if: :all_blank
45
+ end
46
+ end
47
+
48
+ let(:car_class) { CarAllBlank }
49
+ after { Object.send(:remove_const, :CarAllBlank) }
50
+ let(:car) { car_class.create }
51
+ let!(:bar1) { Bar.create(car: car) }
52
+ let!(:bar2) { Bar.create(car: car) }
74
53
 
75
- expect(@car.bars.count).to eq 2
76
- @car.update bars_attributes: [{}, {:id=>@bar1.id, :uno=>"bar1 uno"}]
77
- expect(@car.bars(true).count).to eq 2
54
+ it "should reject attributes when all blank" do
55
+ expect(car.bars.count).to eq 2
56
+ car.update bars_attributes: [{}, {id: bar1.id, uno: "bar1 uno"}]
57
+ expect(car.bars(true).count).to eq 2
78
58
 
79
- @bar1.reload
80
- expect(@bar1.uno).to eq "bar1 uno"
59
+ bar1.reload
60
+ expect(bar1.uno).to eq "bar1 uno"
61
+ end
81
62
  end
82
63
 
83
- it "should reject attributes based on proc" do
84
- @car, @bar1, @bar2 = create_car_with_bars(CarProc)
64
+ context "when reject_if attribute is supplied with a proc" do
65
+ before do
66
+ class CarProc < Car
67
+ accepts_nested_attributes_for :bars, reject_if: ->(attributes) { attributes['uno'].blank? }
68
+ end
69
+ end
85
70
 
86
- @car.update bars_attributes: [{}, {:id=>@bar1.id, :uno=>"bar1 uno"}, {:id=>@bar2.id, :dos=>"bar2 dos"}]
87
- @bar1.reload
88
- @bar2.reload
89
- expect(@bar1.uno).to eq "bar1 uno"
90
- expect(@bar2.dos).to be_nil
91
- end
71
+ after { Object.send(:remove_const, :CarProc) }
72
+ let(:car_class) { CarProc }
73
+
74
+ context "and the reject_if proc evaluates to false" do
75
+ before do
76
+ car.update bars_attributes: [{}, { id: bar1.id, uno: "bar1 uno" }]
77
+ end
78
+ it "updates attributes" do
79
+ expect(bar1.reload.uno).to eq "bar1 uno"
80
+ end
81
+ end
82
+
83
+ context "and the reject_if proc evaluates to true" do
84
+ before do
85
+ car.update bars_attributes: [{}, { id: bar1.id, dos: "bar1 uno" }]
86
+ end
87
+ it "rejects attributes" do
88
+ expect(bar1.reload.dos).to be_nil
89
+ end
90
+ end
92
91
 
93
- it "should reject attributes base on method name" do
94
- @car, @bar1, @bar2 = create_car_with_bars(CarSymbol)
92
+ context "and `allow_destroy: false`" do
93
+ context "and the reject_if proc evaluates to true" do
94
+ before do
95
+ car.update bars_attributes: [{}, { id: bar1.id, dos: "bar1 uno", _destroy: "1" }]
96
+ end
97
+ it "rejects attributes (_destroy doesn't affect the outcome)" do
98
+ expect(bar1.reload.dos).to be_nil
99
+ end
100
+ end
95
101
 
96
- @car.update bars_attributes: [{}, {:id=>@bar1.id, :uno=>"bar1 uno"}, {:id=>@bar2.id, :dos=>"bar2 dos"}]
97
- @bar1.reload
98
- @bar2.reload
99
- expect(@bar1.uno).to eq "bar1 uno"
100
- expect(@bar2.dos).to be_nil
102
+ context "a record with the destroy flag and without an id" do
103
+ it "creates a new record" do
104
+ expect {
105
+ car.update bars_attributes: [{ uno: "bar1 uno", _destroy: "1" }]
106
+ }.not_to change { car.bars(true).count }
107
+ end
108
+ end
109
+ end
101
110
  end
102
111
 
103
- it "should throw TooManyRecords" do
104
- @car, @bar1, @bar2 = create_car_with_bars(CarWithLimit)
112
+ describe "reject_if: with a symbol" do
113
+ before do
114
+ # class used in test for reject_if: with method name as symbol
115
+ class CarSymbol < Car
116
+ accepts_nested_attributes_for :bars, reject_if: :uno_blank
105
117
 
106
- expect {
107
- @car.attributes = {:bars_attributes=>[{}]}
108
- }.to_not raise_exception
118
+ def uno_blank(attributes)
119
+ attributes['uno'].blank?
120
+ end
121
+ end
122
+ end
109
123
 
110
- expect {
111
- @car.attributes = {:bars_attributes=>[{}, {}]}
112
- }.to raise_exception(ActiveFedora::NestedAttributes::TooManyRecords)
124
+ after { Object.send(:remove_const, :CarSymbol) }
125
+ let(:car_class) { CarSymbol }
126
+
127
+ it "rejects attributes based on method name" do
128
+ car.update bars_attributes: [{}, {id: bar1.id, uno: "bar1 uno"}, {id: bar2.id, dos: "bar2 dos"}]
129
+ bar1.reload
130
+ bar2.reload
131
+ expect(bar1.uno).to eq "bar1 uno"
132
+ expect(bar2.dos).to be_nil
133
+ end
113
134
  end
114
135
 
115
- private
136
+ describe "allow_destroy: true" do
137
+ before do
138
+ class CarDestroy < Car
139
+ accepts_nested_attributes_for :bars, allow_destroy: true
140
+ end
141
+ end
116
142
 
117
- # Helper method used to create 1 Car and 2 Bars (with option to provide classes for both models)
118
- #
119
- # @param car_class [class] class for new `car` object, default Car
120
- # @param bar_class [class] class for new `bar` object, default Bar
121
- #
122
- # @return [car,bar,bar] returns 1 Car and 2 Bars
123
- def create_car_with_bars(car_class = Car, bar_class = Bar)
124
- car = car_class.new; car.save!
143
+ let(:car_class) { CarDestroy }
144
+ after { Object.send(:remove_const, :CarDestroy) }
125
145
 
126
- bar1 = bar_class.new(car: car); bar1.save!
127
- bar2 = bar_class.new(car: car); bar2.save!
128
- [car, bar1, bar2]
146
+ it "doesn't create a new record if _destroy is set" do
147
+ expect {
148
+ car.update bars_attributes: [{ uno: "new uno", _destroy: "1" }]
149
+ }.not_to change { car.bars(true).count }
150
+ end
129
151
  end
130
152
 
153
+ describe "limit" do
154
+ before do
155
+ class CarWithLimit < Car
156
+ accepts_nested_attributes_for :bars, limit: 1
157
+ end
158
+ end
159
+ after { Object.send(:remove_const, :CarWithLimit) }
160
+
161
+ let(:car_class) { CarWithLimit }
162
+ it "should throw TooManyRecords" do
163
+ expect {
164
+ car.attributes = {bars_attributes: [{}]}
165
+ }.to_not raise_exception
166
+
167
+ expect {
168
+ car.attributes = {bars_attributes: [{}, {}]}
169
+ }.to raise_exception(ActiveFedora::NestedAttributes::TooManyRecords)
170
+ end
171
+ end
131
172
  end
@@ -232,8 +232,10 @@ describe ActiveFedora::File do
232
232
  end
233
233
  context "with pre-4.3.0 predicate" do
234
234
  before do
235
+ predicate = ::RDF::URI("http://fedora.info/definitions/v4/repository#digest")
236
+ object = RDF::URI.new("urn:sha1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15")
235
237
  graph = ActiveTriples::Resource.new
236
- graph << RDF::Statement.new(file.uri, RDF::Vocab::Fcrepo4.digest, RDF::URI.new("urn:sha1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15"))
238
+ graph << RDF::Statement.new(file.uri, predicate, object)
237
239
  allow(file).to receive_message_chain(:metadata, :ldp_source, :graph).and_return(graph)
238
240
  end
239
241
  it "falls back on fedora:digest if premis:hasMessageDigest is not present" do
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: 9.4.1
4
+ version: 9.4.2
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: 2015-09-18 00:00:00.000000000 Z
13
+ date: 2015-09-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rsolr