ladder 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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