ladder 0.3.2 → 0.4.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.
@@ -58,14 +58,13 @@ module Ladder
58
58
  return unless self._context
59
59
 
60
60
  self._context.each do |field_name, uri|
61
- next if fields.keys.include? field_name
61
+ next if fields[field_name]
62
+ next unless RDF::Vocabulary.find_term(uri)
62
63
 
63
- if RDF::Vocabulary.find_term(uri)
64
- create_accessors field_name
64
+ create_accessors field_name
65
65
 
66
- # Update resource properties
67
- resource_class.property(field_name.to_sym, predicate: RDF::Vocabulary.find_term(uri))
68
- end
66
+ # Apply instance properties to resource
67
+ resource_class.property(field_name.to_sym, predicate: RDF::Vocabulary.find_term(uri))
69
68
  end
70
69
  end
71
70
 
@@ -113,13 +112,15 @@ module Ladder
113
112
  # @see Ladder::Resource#<<
114
113
  #
115
114
  # @param [RDF::Statement, Hash, Array] statement @see RDF::Statement#from
116
- # @return [void]
115
+ # @return [Object, nil] the value inserted into the object
117
116
  def <<(statement)
118
117
  # ActiveTriples::Resource expects: RDF::Statement, Hash, or Array
119
118
  statement = RDF::Statement.from(statement) unless statement.is_a? RDF::Statement
120
119
 
121
- # Don't store statically-defined types
122
- return if resource_class.type == statement.object
120
+ case statement.object
121
+ when resource_class.type then return # Don't store statically-defined types
122
+ when RDF::Node then return super # Delegate nodes (relations) to parent
123
+ end
123
124
 
124
125
  if RDF.type == statement.predicate
125
126
  # Store type information
@@ -131,9 +132,12 @@ module Ladder
131
132
  end
132
133
 
133
134
  # If we have an undefined predicate, then dynamically define it
134
- return unless statement.predicate.qname
135
135
  property statement.predicate.qname.last, predicate: statement.predicate unless field_from_predicate statement.predicate
136
136
 
137
+ if self._context && self._context.values.include?(statement.predicate.to_s)
138
+ send("#{self._context.key(statement.predicate.to_s)}=", statement.object.to_s)
139
+ end
140
+
137
141
  super
138
142
  end
139
143
 
@@ -1,17 +1,30 @@
1
1
  require 'json/ld'
2
+ require 'rdf/turtle'
2
3
 
3
4
  module Ladder
4
5
  module Resource
5
6
  module Serializable
7
+ ##
8
+ # Return a Turtle representation for the resource
9
+ #
10
+ # @see ActiveTriples::Resource#dump
11
+ #
12
+ # @param [Hash] opts options to pass to ActiveTriples
13
+ # @option opts [Boolean] :related whether to include related resources (default: false)
14
+ # @return [String] a serialized Turtle version of the resource
15
+ def as_turtle(opts = { related: false })
16
+ update_resource(opts.slice :related).dump(:ttl, { standard_prefixes: true }.merge(opts))
17
+ end
18
+
6
19
  ##
7
20
  # Return a JSON-LD representation for the resource
8
21
  #
9
22
  # @see ActiveTriples::Resource#dump
10
23
  #
11
24
  # @param [Hash] opts options to pass to ActiveTriples
12
- # @option opts [Boolean] :related whether to include related resources
25
+ # @option opts [Boolean] :related whether to include related resources (default: false)
13
26
  # @return [Hash] a serialized JSON-LD version of the resource
14
- def as_jsonld(opts = {})
27
+ def as_jsonld(opts = { related: false })
15
28
  JSON.parse update_resource(opts.slice :related).dump(:jsonld, { standard_prefixes: true }.merge(opts))
16
29
  end
17
30
 
@@ -46,13 +59,11 @@ module Ladder
46
59
  ns, name = property.predicate.qname
47
60
  qname_hash[ns] ||= {}
48
61
 
49
- if relations.keys.include? field_name
50
- if opts[:related]
51
- qname_hash[ns][name] = send(field_name).to_a.map(&:as_qname)
52
- else
53
- qname_hash[ns][name] = send(field_name).to_a.map { |obj| "#{obj.class.name.underscore.pluralize}:#{obj.id}" }
54
- end
55
- elsif fields.keys.include? field_name
62
+ if relations[field_name]
63
+ qname_hash[ns][name] = opts[:related] ? send(field_name).to_a.map(&:as_qname) : send(field_name).to_a.map { |obj| "#{obj.class.name.underscore.pluralize}:#{obj.id}" }
64
+ end
65
+
66
+ if fields[field_name]
56
67
  qname_hash[ns][name] = read_attribute(field_name)
57
68
  end
58
69
 
@@ -60,7 +71,8 @@ module Ladder
60
71
  qname_hash[ns].delete_if { |_k, v| v.blank? }
61
72
  end
62
73
 
63
- qname_hash
74
+ # Insert labels for boosting search score
75
+ { rdfs: { label: update_resource(opts.slice :related).rdf_label } }.merge qname_hash
64
76
  end
65
77
  end
66
78
  end
@@ -1,3 +1,3 @@
1
1
  module Ladder
2
- VERSION = '0.3.2'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -2,24 +2,18 @@ require 'spec_helper'
2
2
 
3
3
  describe Ladder::File do
4
4
  before do
5
- Mongoid.load!('mongoid.yml', :development)
6
- Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
7
- Mongoid.purge!
8
-
9
- LADDER_BASE_URI ||= 'http://example.org'
10
-
11
5
  class Datastream
12
6
  include Ladder::File
13
7
  end
14
8
  end
15
9
 
16
10
  after do
17
- Object.send(:remove_const, :LADDER_BASE_URI) if Object
11
+ Ladder::Config.models.delete Datastream
18
12
  Object.send(:remove_const, 'Datastream') if Object
19
13
  end
20
14
 
21
15
  shared_context 'with relations' do
22
- let(:thing) { Thing.new }
16
+ let(:thing) { Thing.new }
23
17
 
24
18
  before do
25
19
  class Thing
@@ -37,6 +31,7 @@ describe Ladder::File do
37
31
  end
38
32
 
39
33
  after do
34
+ Ladder::Config.models.delete Thing
40
35
  Object.send(:remove_const, 'Thing') if Object
41
36
  end
42
37
 
@@ -2,37 +2,39 @@ require 'spec_helper'
2
2
 
3
3
  describe Ladder::Resource::Dynamic do
4
4
  before do
5
- Mongoid.load!('mongoid.yml', :development)
6
- Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
7
- Mongoid.purge!
8
-
9
- LADDER_BASE_URI ||= 'http://example.org'
10
-
11
5
  class Thing
12
6
  include Ladder::Resource::Dynamic
7
+
8
+ # FIXME: DRY out this block
13
9
  configure type: RDF::DC.BibliographicResource
14
10
 
15
- field :alt
16
- property :alt, predicate: RDF::DC.alternative # non-localized literal
17
- property :title, predicate: RDF::DC.title # localized literal
11
+ property :title, predicate: RDF::DC.title # localized String
12
+ property :alt, predicate: RDF::DC.alternative, # non-localized String
13
+ localize: false
14
+ property :references, predicate: RDF::DC.references # URI
15
+ property :referenced, predicate: RDF::DC.isReferencedBy # Array
16
+ property :is_valid, predicate: RDF::DC.valid # Boolean
17
+ property :date, predicate: RDF::DC.date # Date
18
+ property :issued, predicate: RDF::DC.issued # DateTime
19
+ property :spatial, predicate: RDF::DC.spatial # Float
20
+ # property :conformsTo, predicate: RDF::DC.conformsTo # Hash
21
+ property :identifier, predicate: RDF::DC.identifier # Integer
22
+ # property :license, predicate: RDF::DC.license # Range
23
+ property :source, predicate: RDF::DC.source # Symbol
24
+ property :created, predicate: RDF::DC.created # Time
25
+ ###
18
26
  end
19
27
  end
20
28
 
21
29
  after do
22
- Object.send(:remove_const, :LADDER_BASE_URI) if Object
30
+ Ladder::Config.models.delete Thing
23
31
  Object.send(:remove_const, 'Thing') if Object
24
32
  end
25
33
 
26
34
  context 'with data' do
27
35
  let(:subject) { Thing.new }
28
36
 
29
- before do
30
- # non-localized literal
31
- subject.alt = 'Mumintrollet pa kometjakt'
32
-
33
- # localized literal
34
- subject.title = 'Comet in Moominland'
35
- end
37
+ include_context 'with data'
36
38
 
37
39
  it_behaves_like 'a Resource'
38
40
  it_behaves_like 'a Dynamic Resource'
@@ -2,25 +2,32 @@ require 'spec_helper'
2
2
 
3
3
  describe Ladder::Resource do
4
4
  before do
5
- Mongoid.load!('mongoid.yml', :development)
6
- Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
7
- Mongoid.purge!
8
-
9
- LADDER_BASE_URI ||= 'http://example.org'
10
-
11
5
  class Thing
12
6
  include Ladder::Resource
7
+
8
+ # FIXME: DRY out this block
13
9
  configure type: RDF::DC.BibliographicResource
14
10
 
15
- field :alt
16
- property :alt, predicate: RDF::DC.alternative # non-localized literal
17
- property :title, predicate: RDF::DC.title # localized literal
18
- property :identifier, predicate: RDF::DC.identifier
11
+ property :title, predicate: RDF::DC.title # localized String
12
+ property :alt, predicate: RDF::DC.alternative, # non-localized String
13
+ localize: false
14
+ property :references, predicate: RDF::DC.references # URI
15
+ property :referenced, predicate: RDF::DC.isReferencedBy # Array
16
+ property :is_valid, predicate: RDF::DC.valid # Boolean
17
+ property :date, predicate: RDF::DC.date # Date
18
+ property :issued, predicate: RDF::DC.issued # DateTime
19
+ property :spatial, predicate: RDF::DC.spatial # Float
20
+ # property :conformsTo, predicate: RDF::DC.conformsTo # Hash
21
+ property :identifier, predicate: RDF::DC.identifier # Integer
22
+ # property :license, predicate: RDF::DC.license # Range
23
+ property :source, predicate: RDF::DC.source # Symbol
24
+ property :created, predicate: RDF::DC.created # Time
25
+ ###
19
26
  end
20
27
  end
21
28
 
22
29
  after do
23
- Object.send(:remove_const, :LADDER_BASE_URI) if Object
30
+ Ladder::Config.models.delete Thing
24
31
  Object.send(:remove_const, 'Thing') if Object
25
32
  end
26
33
 
@@ -47,7 +54,7 @@ describe Ladder::Resource do
47
54
  configure type: RDF::DC.PhysicalResource
48
55
 
49
56
  embedded_in :thing
50
- property :thing, predicate: RDF::DC.relation, class_name: 'Thing'
57
+ property :thing, predicate: RDF::DC.isPartOf, class_name: 'Thing'
51
58
  end
52
59
 
53
60
  # many-to-many
@@ -63,6 +70,10 @@ describe Ladder::Resource do
63
70
  end
64
71
 
65
72
  after do
73
+ Ladder::Config.models.delete Person
74
+ Ladder::Config.models.delete Concept
75
+ Ladder::Config.models.delete Part
76
+
66
77
  Object.send(:remove_const, 'Person') if Object
67
78
  Object.send(:remove_const, 'Concept') if Object
68
79
  Object.send(:remove_const, 'Part') if Object
@@ -77,6 +88,26 @@ describe Ladder::Resource do
77
88
  it_behaves_like 'a Resource'
78
89
  end
79
90
 
91
+ context 'with subclass' do
92
+ before do
93
+ class Subthing < Thing
94
+ # types are not inherited, so we must set it explicitly
95
+ configure type: RDF::DC.BibliographicResource
96
+ end
97
+ end
98
+
99
+ after do
100
+ Ladder::Config.models.delete Subthing
101
+ Object.send(:remove_const, 'Subthing') if Object
102
+ end
103
+
104
+ let(:subject) { Subthing.new }
105
+
106
+ include_context 'with data'
107
+
108
+ it_behaves_like 'a Resource'
109
+ end
110
+
80
111
  context 'with relations' do
81
112
  let(:subject) { Thing.new }
82
113
 
@@ -2,23 +2,30 @@ require 'spec_helper'
2
2
 
3
3
  describe Ladder::Searchable::Background do
4
4
  before do
5
- Mongoid.load!('mongoid.yml', :development)
6
- Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
7
- Mongoid.purge!
8
-
9
- Elasticsearch::Model.client = Elasticsearch::Client.new host: 'localhost:9200', log: true
10
- Elasticsearch::Model.client.indices.delete index: '_all'
11
-
12
- LADDER_BASE_URI ||= 'http://example.org'
5
+ Elasticsearch::Client.new(host: 'localhost:9200', log: true).indices.delete index: '_all'
13
6
 
14
7
  class Thing
15
8
  include Ladder::Resource
16
9
  include Ladder::Searchable::Background
10
+
11
+ # FIXME: DRY out this block
17
12
  configure type: RDF::DC.BibliographicResource
18
13
 
19
- field :alt
20
- property :alt, predicate: RDF::DC.alternative # non-localized literal
21
- property :title, predicate: RDF::DC.title # localized literal
14
+ property :title, predicate: RDF::DC.title # localized String
15
+ property :alt, predicate: RDF::DC.alternative, # non-localized String
16
+ localize: false
17
+ property :references, predicate: RDF::DC.references # URI
18
+ property :referenced, predicate: RDF::DC.isReferencedBy # Array
19
+ property :is_valid, predicate: RDF::DC.valid # Boolean
20
+ property :date, predicate: RDF::DC.date # Date
21
+ property :issued, predicate: RDF::DC.issued # DateTime
22
+ property :spatial, predicate: RDF::DC.spatial # Float
23
+ # property :conformsTo, predicate: RDF::DC.conformsTo # Hash
24
+ property :identifier, predicate: RDF::DC.identifier # Integer
25
+ # property :license, predicate: RDF::DC.license # Range
26
+ property :source, predicate: RDF::DC.source # Symbol
27
+ property :created, predicate: RDF::DC.created # Time
28
+ ###
22
29
  end
23
30
 
24
31
  class Datastream
@@ -28,13 +35,15 @@ describe Ladder::Searchable::Background do
28
35
  end
29
36
 
30
37
  after do
31
- Object.send(:remove_const, :LADDER_BASE_URI) if Object
38
+ Ladder::Config.models.delete Thing
39
+ Ladder::Config.models.delete Datastream
40
+
32
41
  Object.send(:remove_const, 'Thing') if Object
33
42
  Object.send(:remove_const, 'Datastream') if Object
34
43
  end
35
44
 
36
45
  shared_context 'with relations' do
37
- let(:person) { Person.new }
46
+ let(:person) { Person.new }
38
47
 
39
48
  before do
40
49
  class Person
@@ -48,6 +57,7 @@ describe Ladder::Searchable::Background do
48
57
  end
49
58
 
50
59
  after do
60
+ Ladder::Config.models.delete Person
51
61
  Object.send(:remove_const, 'Person') if Object
52
62
  end
53
63
  end
@@ -2,14 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Ladder::Searchable::File do
4
4
  before do
5
- Mongoid.load!('mongoid.yml', :development)
6
- Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
7
- Mongoid.purge!
8
-
9
- Elasticsearch::Model.client = Elasticsearch::Client.new host: 'localhost:9200', log: true
10
- Elasticsearch::Model.client.indices.delete index: '_all'
11
-
12
- LADDER_BASE_URI ||= 'http://example.org'
5
+ Elasticsearch::Client.new(host: 'localhost:9200', log: true).indices.delete index: '_all'
13
6
 
14
7
  class Datastream
15
8
  include Ladder::File
@@ -18,6 +11,7 @@ describe Ladder::Searchable::File do
18
11
  end
19
12
 
20
13
  after do
14
+ Ladder::Config.models.delete Datastream
21
15
  Object.send(:remove_const, 'Datastream') if Object
22
16
  end
23
17
 
@@ -2,28 +2,35 @@ require 'spec_helper'
2
2
 
3
3
  describe Ladder::Searchable::Resource do
4
4
  before do
5
- Mongoid.load!('mongoid.yml', :development)
6
- Mongoid.logger.level = Moped.logger.level = Logger::DEBUG
7
- Mongoid.purge!
8
-
9
- Elasticsearch::Model.client = Elasticsearch::Client.new host: 'localhost:9200', log: true
10
- Elasticsearch::Model.client.indices.delete index: '_all'
11
-
12
- LADDER_BASE_URI ||= 'http://example.org'
5
+ Elasticsearch::Client.new(host: 'localhost:9200', log: true).indices.delete index: '_all'
13
6
 
14
7
  class Thing
15
8
  include Ladder::Resource
16
9
  include Ladder::Searchable
10
+
11
+ # FIXME: DRY out this block
17
12
  configure type: RDF::DC.BibliographicResource
18
13
 
19
- field :alt
20
- property :alt, predicate: RDF::DC.alternative # non-localized literal
21
- property :title, predicate: RDF::DC.title # localized literal
14
+ property :title, predicate: RDF::DC.title # localized String
15
+ property :alt, predicate: RDF::DC.alternative, # non-localized String
16
+ localize: false
17
+ property :references, predicate: RDF::DC.references # URI
18
+ property :referenced, predicate: RDF::DC.isReferencedBy # Array
19
+ property :is_valid, predicate: RDF::DC.valid # Boolean
20
+ property :date, predicate: RDF::DC.date # Date
21
+ property :issued, predicate: RDF::DC.issued # DateTime
22
+ property :spatial, predicate: RDF::DC.spatial # Float
23
+ # property :conformsTo, predicate: RDF::DC.conformsTo # Hash
24
+ property :identifier, predicate: RDF::DC.identifier # Integer
25
+ # property :license, predicate: RDF::DC.license # Range
26
+ property :source, predicate: RDF::DC.source # Symbol
27
+ property :created, predicate: RDF::DC.created # Time
28
+ ###
22
29
  end
23
30
  end
24
31
 
25
32
  after do
26
- Object.send(:remove_const, :LADDER_BASE_URI) if Object
33
+ Ladder::Config.models.delete Thing
27
34
  Object.send(:remove_const, 'Thing') if Object
28
35
  end
29
36
 
@@ -42,6 +49,7 @@ describe Ladder::Searchable::Resource do
42
49
  end
43
50
 
44
51
  after do
52
+ Ladder::Config.models.delete Person
45
53
  Object.send(:remove_const, 'Person') if Object
46
54
  end
47
55
  end