rdf-mapper 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +188 -0
- data/UNLICENSE +25 -0
- data/VERSION +1 -0
- data/lib/lib/adapters/base.rb +83 -0
- data/lib/lib/adapters/rails.rb +307 -0
- data/lib/lib/adapters/rest.rb +45 -0
- data/lib/lib/adapters/sparql.rb +105 -0
- data/lib/lib/associations/base.rb +95 -0
- data/lib/lib/associations/belongs_to.rb +64 -0
- data/lib/lib/associations/has_and_belongs.rb +17 -0
- data/lib/lib/associations/has_many.rb +147 -0
- data/lib/lib/associations/has_one.rb +17 -0
- data/lib/lib/model/association.rb +59 -0
- data/lib/lib/model/attribute.rb +186 -0
- data/lib/lib/model/base.rb +623 -0
- data/lib/lib/model/output.rb +70 -0
- data/lib/lib/model/property.rb +78 -0
- data/lib/lib/scope/collection.rb +165 -0
- data/lib/lib/scope/condition.rb +132 -0
- data/lib/lib/scope/loader.rb +111 -0
- data/lib/lib/scope/model.rb +129 -0
- data/lib/lib/scope/query.rb +281 -0
- data/lib/lib/util/http.rb +66 -0
- data/lib/lib/util/logger.rb +68 -0
- data/lib/rdf-mapper.rb +15 -0
- metadata +141 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Adapters
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class SPARQL < Base
|
7
|
+
|
8
|
+
##
|
9
|
+
# [-]
|
10
|
+
##
|
11
|
+
def initialize(cls, options = {})
|
12
|
+
@rdf, @options = cls, options
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# [-]
|
17
|
+
##
|
18
|
+
def load(query)
|
19
|
+
Query.new(query, @options).find
|
20
|
+
end
|
21
|
+
|
22
|
+
class Query
|
23
|
+
|
24
|
+
include RDFMapper::Logger
|
25
|
+
|
26
|
+
##
|
27
|
+
# [-]
|
28
|
+
##
|
29
|
+
def initialize(query, options = {})
|
30
|
+
@query, @options = query, options
|
31
|
+
@rdf = @query.cls
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# [-]
|
36
|
+
##
|
37
|
+
def find
|
38
|
+
describe
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
##
|
45
|
+
# [-]
|
46
|
+
##
|
47
|
+
def describe
|
48
|
+
data = sparql_writer(:describe) do |writer|
|
49
|
+
triples = @query.to_triples
|
50
|
+
writer.write_triples(triples)
|
51
|
+
# Target always comes first in first triple
|
52
|
+
primary = triples.first.first
|
53
|
+
writer.targets << primary
|
54
|
+
end
|
55
|
+
repository = {}
|
56
|
+
download(data).each_triple do |triple|
|
57
|
+
s, p, o = triple
|
58
|
+
repository[s.to_s] ||= {}
|
59
|
+
repository[s.to_s][p.to_s] ||= []
|
60
|
+
repository[s.to_s][p.to_s] << o
|
61
|
+
end
|
62
|
+
objects(repository)
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# [-]
|
67
|
+
##
|
68
|
+
def objects(repository)
|
69
|
+
repository.select do |uri, atts|
|
70
|
+
atts.key?(RDF.type.to_s)
|
71
|
+
end.select do |uri, atts|
|
72
|
+
@rdf.type == atts[RDF.type.to_s].first
|
73
|
+
end.map do |uri, atts|
|
74
|
+
atts.delete(RDF.type.to_s)
|
75
|
+
atts[:id] = uri
|
76
|
+
atts
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# [-]
|
82
|
+
##
|
83
|
+
def sparql_writer(type, &block)
|
84
|
+
RDF::Writer.for(:sparql).buffer({ :type => type }, &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# [-]
|
89
|
+
##
|
90
|
+
def download(request)
|
91
|
+
data = RDFMapper::HTTP.post(@options[:server], request)
|
92
|
+
|
93
|
+
if data =~ /\<sparql/
|
94
|
+
RDF::Reader.for(:sparql_results)
|
95
|
+
elsif data =~ /\<rdf:RDF/
|
96
|
+
RDF::Reader.for(:xml)
|
97
|
+
else
|
98
|
+
raise RuntimeError, 'Unknown content type'
|
99
|
+
end.new(data)
|
100
|
+
end
|
101
|
+
|
102
|
+
end # Query
|
103
|
+
end # SPARQL
|
104
|
+
end # Adapters
|
105
|
+
end # RDFMapper
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
autoload :BelongsTo, 'lib/associations/belongs_to'
|
5
|
+
autoload :HasMany, 'lib/associations/has_many'
|
6
|
+
autoload :HasOne, 'lib/associations/has_one'
|
7
|
+
autoload :HasAndBelongs, 'lib/associations/has_and_belongs'
|
8
|
+
|
9
|
+
##
|
10
|
+
# Base class for all association types. Contains default constructor.
|
11
|
+
##
|
12
|
+
class Base
|
13
|
+
|
14
|
+
include RDFMapper::Logger
|
15
|
+
|
16
|
+
def initialize(instance, options = {})
|
17
|
+
@instance = instance
|
18
|
+
@association = options[:cls]
|
19
|
+
@options = options
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# [-]
|
24
|
+
##
|
25
|
+
def replace(value)
|
26
|
+
raise NotImplementedError, 'Expected association to override `replace`'
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# [-]
|
31
|
+
##
|
32
|
+
def object(force = false)
|
33
|
+
value.nil? and value.empty? if force
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# [-]
|
39
|
+
##
|
40
|
+
def to_statements(options = {})
|
41
|
+
options[:skip] ||= []
|
42
|
+
if value.kind_of? Array
|
43
|
+
items = value
|
44
|
+
else
|
45
|
+
items = [value]
|
46
|
+
end
|
47
|
+
items.reject do |item|
|
48
|
+
options[:skip].include?(items)
|
49
|
+
end.map do |item|
|
50
|
+
node = if options[:full]
|
51
|
+
item.to_statements(:skip => @instance)
|
52
|
+
else
|
53
|
+
item.to_statements(:short => true)
|
54
|
+
end
|
55
|
+
node + [{
|
56
|
+
:subject => @instance.id,
|
57
|
+
:predicate => @options[:type],
|
58
|
+
:object => item.id
|
59
|
+
}]
|
60
|
+
end.flatten
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Developer-friendly representation of the instance
|
65
|
+
#
|
66
|
+
# @return [String]
|
67
|
+
##
|
68
|
+
def inspect #nodoc
|
69
|
+
value.inspect
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
##
|
76
|
+
# [-]
|
77
|
+
##
|
78
|
+
def value
|
79
|
+
raise NotImplementedError, 'Expected association to override `value`'
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# [-]
|
84
|
+
##
|
85
|
+
def method_missing(symbol, *args, &block)
|
86
|
+
if value.respond_to? symbol
|
87
|
+
value.send(symbol, *args, &block)
|
88
|
+
else
|
89
|
+
raise RuntimeError, 'Undefined method `%s`' % symbol
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end # Base
|
94
|
+
end # Associations
|
95
|
+
end # RDFMapper
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class BelongsTo < Base
|
7
|
+
|
8
|
+
##
|
9
|
+
# [-]
|
10
|
+
##
|
11
|
+
def id
|
12
|
+
value.id
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# [-]
|
17
|
+
##
|
18
|
+
def nil?
|
19
|
+
value.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# [-]
|
24
|
+
##
|
25
|
+
def kind_of?(type)
|
26
|
+
value.kind_of?(type)
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Replaces current association with a new object
|
31
|
+
##
|
32
|
+
def replace(value)
|
33
|
+
if value.kind_of? String
|
34
|
+
@key = RDF::URI.new(value)
|
35
|
+
end
|
36
|
+
if value.kind_of? RDF::URI
|
37
|
+
@key = value
|
38
|
+
end
|
39
|
+
if value.kind_of? RDFMapper::Model
|
40
|
+
@value = value
|
41
|
+
else
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
##
|
50
|
+
# [-]
|
51
|
+
##
|
52
|
+
def value
|
53
|
+
unless @value.nil?
|
54
|
+
return @value
|
55
|
+
end
|
56
|
+
if @key.nil?
|
57
|
+
return nil
|
58
|
+
end
|
59
|
+
replace(@association.find(@key))
|
60
|
+
end
|
61
|
+
|
62
|
+
end # BelongsTo
|
63
|
+
end # Associations
|
64
|
+
end # RDFMapper
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class HasAndBelongs
|
7
|
+
|
8
|
+
##
|
9
|
+
# [-]
|
10
|
+
##
|
11
|
+
def initialize(instance, options = {})
|
12
|
+
raise NotImplementedError, 'has_and_belongs_to is not yet implemented'
|
13
|
+
end
|
14
|
+
|
15
|
+
end # HasAndBelongs
|
16
|
+
end # Associations
|
17
|
+
end # RDFMapper
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class HasMany < Base
|
7
|
+
|
8
|
+
##
|
9
|
+
# Replaces the collections content by deleting and adding
|
10
|
+
# objects as appropriate.
|
11
|
+
##
|
12
|
+
def replace(objects)
|
13
|
+
new_objects = filter(objects.to_a)
|
14
|
+
return @value if new_objects.empty?
|
15
|
+
|
16
|
+
new_objects.each do |child|
|
17
|
+
self << child
|
18
|
+
end
|
19
|
+
|
20
|
+
@value ||= []
|
21
|
+
@value.each do |child|
|
22
|
+
delete(child) unless new_objects.include?(child)
|
23
|
+
end
|
24
|
+
|
25
|
+
@value
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Adds one or more objects to the collection by setting their
|
30
|
+
# foreign keys to the collection's primary key.
|
31
|
+
##
|
32
|
+
def <<(*objects)
|
33
|
+
objects.to_a.select do |child|
|
34
|
+
child.kind_of? RDFMapper::Model
|
35
|
+
end.each do |child|
|
36
|
+
unless include?(child)
|
37
|
+
child[reverse] = @instance
|
38
|
+
@value << child
|
39
|
+
end
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
alias_method :push, :<<
|
45
|
+
|
46
|
+
##
|
47
|
+
# Removes one or more objects from the collection by removing
|
48
|
+
# the association between objects
|
49
|
+
##
|
50
|
+
def delete(*objects)
|
51
|
+
objects.each do |child|
|
52
|
+
if include?(child)
|
53
|
+
child[reverse] = nil
|
54
|
+
@value.delete(child)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Removes every object from the collection.
|
62
|
+
##
|
63
|
+
def clear
|
64
|
+
delete(@value)
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Finds an associated object according to the same rules as
|
69
|
+
# RDFMapper::Model.find.
|
70
|
+
##
|
71
|
+
def find
|
72
|
+
raise NotImplementedError, '`find` not yet implemented' # TODO
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Returns one or more new objects of the collection type that
|
77
|
+
# have been instantiated with attributes and linked to this object
|
78
|
+
# through a foreign key, but have not yet been saved.
|
79
|
+
##
|
80
|
+
def build
|
81
|
+
raise NotImplementedError, '`build` not yet implemented' # TODO
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Returns a new object of the collection type that has been
|
86
|
+
# instantiated with attributes, linked to this object through
|
87
|
+
# a foreign key, and that has already been saved.
|
88
|
+
##
|
89
|
+
def create
|
90
|
+
raise NotImplementedError, '`create` not yet implemented' # TODO
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Returns true if a given object is present in the collection
|
95
|
+
##
|
96
|
+
def include?(object)
|
97
|
+
@value ||= []
|
98
|
+
@value.include?(object)
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# [-]
|
103
|
+
##
|
104
|
+
def to_a
|
105
|
+
value
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def filter(objects)
|
112
|
+
objects.select do |child|
|
113
|
+
child.kind_of? RDFMapper::Model
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# [-]
|
119
|
+
##
|
120
|
+
def value
|
121
|
+
unless @value.nil?
|
122
|
+
return @value
|
123
|
+
end
|
124
|
+
if @instance.id.nil?
|
125
|
+
return []
|
126
|
+
end
|
127
|
+
replace @association.find(:all, {
|
128
|
+
:conditions => { reverse => @instance },
|
129
|
+
:skip => [reverse]
|
130
|
+
})
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# [-]
|
135
|
+
##
|
136
|
+
def reverse
|
137
|
+
@reverse ||= @association.has?(nil, @instance)
|
138
|
+
if @reverse.nil?
|
139
|
+
raise RuntimeError, 'Expected %s to belong to %s' % [@association, @instance.class]
|
140
|
+
else
|
141
|
+
@reverse.name
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end # HasMany
|
146
|
+
end # Associations
|
147
|
+
end # RDFMapper
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class HasOne
|
7
|
+
|
8
|
+
##
|
9
|
+
# [-]
|
10
|
+
##
|
11
|
+
def initialize(instance, options = {})
|
12
|
+
raise NotImplementedError, 'has_one is not yet implemented'
|
13
|
+
end
|
14
|
+
|
15
|
+
end # HasOne
|
16
|
+
end # Associations
|
17
|
+
end # RDFMapper
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
class Model
|
3
|
+
class << self
|
4
|
+
|
5
|
+
##
|
6
|
+
# Specifies a one-to-many association. The following methods for retrieval
|
7
|
+
# and query of collections of associated objects will be added:
|
8
|
+
#
|
9
|
+
# * collection(force_load = false) -- Returns an array of all the associated
|
10
|
+
# objects. An empty array is returned if none are found.
|
11
|
+
#
|
12
|
+
# * collection<<(object, ...) -- Adds one or more objects to the collection by
|
13
|
+
# setting their foreign keys to the collection‘s primary key.
|
14
|
+
#
|
15
|
+
# * collection.delete(object, ...) -- Removes one or more objects from the
|
16
|
+
# collection by removing the association between objects.
|
17
|
+
#
|
18
|
+
# * collection=objects -- Replaces the collections content by deleting and
|
19
|
+
# adding objects as appropriate.
|
20
|
+
#
|
21
|
+
# * collection.clear -- Removes every object from the collection.
|
22
|
+
#
|
23
|
+
# * collection.empty? -- Returns true if there are no associated objects.
|
24
|
+
#
|
25
|
+
# * collection.size -- Returns the number of associated objects.
|
26
|
+
#
|
27
|
+
# @param [Symbol] name name of the association
|
28
|
+
#
|
29
|
+
# @param [Symbol] options[:class_name] class name of the association. Use it
|
30
|
+
# only if that name can't be inferred from the association name
|
31
|
+
#
|
32
|
+
# @return [Object] instance of RDFMapper::Attribute
|
33
|
+
##
|
34
|
+
def has_many(name, options = {})
|
35
|
+
attribute(name, options.merge(:association => :has_many))
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Specifies a one-to-one association with another class. The following
|
40
|
+
# methods for retrieval and query of the associated object will be added:
|
41
|
+
#
|
42
|
+
# * association(force_reload = false) -- Returns the associated object.
|
43
|
+
# nil is returned if none is found.
|
44
|
+
#
|
45
|
+
# * association=(associate) -- Assigns the associate object.
|
46
|
+
#
|
47
|
+
# @param [Symbol] name name of the association
|
48
|
+
#
|
49
|
+
# @param [Symbol] options[:class_name] class name of the association. Use it
|
50
|
+
# only if that name can't be inferred from the association name
|
51
|
+
##
|
52
|
+
def belongs_to(name, options = {})
|
53
|
+
attribute(name, options.merge(:association => :belongs_to))
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end # Model
|
58
|
+
end # RDFMapper
|
59
|
+
|
@@ -0,0 +1,186 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
class Model
|
3
|
+
##
|
4
|
+
# Contains configuration and convenience methods for model attributes.
|
5
|
+
# Instances of this class are assigned to classes (not instances!) of
|
6
|
+
# RDFMapper::Model.
|
7
|
+
##
|
8
|
+
class Attribute
|
9
|
+
|
10
|
+
include RDFMapper::Logger
|
11
|
+
|
12
|
+
attr_reader :name
|
13
|
+
|
14
|
+
##
|
15
|
+
# Constructor is called for each attribute of a model at the time
|
16
|
+
# the model is defined.
|
17
|
+
#
|
18
|
+
# @param [Object] cls class of the model
|
19
|
+
# @param [String] name name of the attribute
|
20
|
+
# @param [Hash] options options to pass on to the property / association constructor
|
21
|
+
#
|
22
|
+
# @return [self]
|
23
|
+
##
|
24
|
+
def initialize(cls, name, options)
|
25
|
+
@cls = cls
|
26
|
+
@name = name
|
27
|
+
@options = options.dup
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Checks if this attribute is a `belongs_to` association.
|
32
|
+
#
|
33
|
+
# @return [Boolean]
|
34
|
+
##
|
35
|
+
def belongs_to?
|
36
|
+
not property? and not multiple?
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Checks if this attribute is a property (i.e. not an association).
|
41
|
+
#
|
42
|
+
# @return [Boolean]
|
43
|
+
##
|
44
|
+
def property?
|
45
|
+
@options[:association].nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Returns attribute's RDF predicate.
|
50
|
+
#
|
51
|
+
# @return [RDF::URI]
|
52
|
+
# @return [nil] if not specified and model has no namespace
|
53
|
+
##
|
54
|
+
def type
|
55
|
+
# Type is 'cached': lookups based on namespace can be quite slow
|
56
|
+
@type ||= unless @options[:predicate].nil?
|
57
|
+
RDF::URI.new(@options[:predicate].to_s)
|
58
|
+
else
|
59
|
+
# Keep this weird comparison. RDF::Vocabulary doesn't recognize `nil?` or `==`
|
60
|
+
(nil == @cls.namespace) ? nil : @cls.namespace[@name]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Returns class of the associated model. Uses either the `:class_name`
|
66
|
+
# option or relies on association name. It follows ActiveRecord naming
|
67
|
+
# conventions(e.g. has_many should be plural, belongs_to - singular).
|
68
|
+
#
|
69
|
+
# @return [Object] a subclass of RDFMapper::Model
|
70
|
+
# @return [nil] if association is not found or this is a property attribute
|
71
|
+
##
|
72
|
+
def model
|
73
|
+
# A bit of 'caching': lookups based on namespace can be quite slow
|
74
|
+
unless @model.nil?
|
75
|
+
return @model
|
76
|
+
end
|
77
|
+
|
78
|
+
# Should return nil if this is not an association
|
79
|
+
if property?
|
80
|
+
return nil
|
81
|
+
end
|
82
|
+
|
83
|
+
if @model = model_from_options || model_from_namespace
|
84
|
+
@model
|
85
|
+
else
|
86
|
+
raise RuntimeError, 'Could not find association model for %s (%s :%s)' % [@cls, @options[:association], @name]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Returns the class or an instance of a class associated with this
|
92
|
+
# attribute.
|
93
|
+
|
94
|
+
# When model instance is not specified, it will return Associations::HasMany,
|
95
|
+
# Associations::BelongsTo, Property, etc. Alternatively, when RDFMapper::Model
|
96
|
+
# is specified, it will return an instance of these classes.
|
97
|
+
#
|
98
|
+
# @param [Object] instance instance of RDFMapper::Model
|
99
|
+
# @return [Object] class of this attribute
|
100
|
+
# @return [Object] instance of this attribute
|
101
|
+
##
|
102
|
+
def value(instance = nil)
|
103
|
+
if nil == instance
|
104
|
+
return attribute_type
|
105
|
+
end
|
106
|
+
attribute_type.new(instance, @options.merge({
|
107
|
+
:cls => model,
|
108
|
+
:type => type,
|
109
|
+
:name => name
|
110
|
+
}))
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Checks if this attribute has the same predicate and / or value.
|
115
|
+
# Value is accepted both as an instance and a class.
|
116
|
+
##
|
117
|
+
def matches?(predicate, value = nil)
|
118
|
+
if type.nil? # Always false if attribute predicate is not defined
|
119
|
+
return false
|
120
|
+
end
|
121
|
+
if value == nil # Checking predicates
|
122
|
+
return type.to_s == predicate.to_s
|
123
|
+
end
|
124
|
+
unless value.respond_to? :new # Converting instance to a class
|
125
|
+
value = value.class
|
126
|
+
end
|
127
|
+
if model.nil? # Value is not nil, but model is undefined
|
128
|
+
return false
|
129
|
+
end
|
130
|
+
if value.type != model.type # Value type and model type should match
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
if predicate.nil? # Value and model types match
|
134
|
+
true
|
135
|
+
else
|
136
|
+
predicate == type
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
##
|
144
|
+
# Returns attribute's class (e.g. Associations::HasMany, Property) based
|
145
|
+
# on the supplied `options[:association]`
|
146
|
+
##
|
147
|
+
def attribute_type #nodoc
|
148
|
+
case @options[:association]
|
149
|
+
when :has_many then Associations::HasMany
|
150
|
+
when :belongs_to then Associations::BelongsTo
|
151
|
+
when :has_one then Association::HasOne
|
152
|
+
when :has_and_belongs then Association::HasAndBelongs
|
153
|
+
else Property
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
##
|
158
|
+
# Derives the name of associated model from `options[:class_name]` and
|
159
|
+
# returns its class.
|
160
|
+
##
|
161
|
+
def model_from_options #nodoc
|
162
|
+
@options[:class_name].nil? ? nil : @options[:class_name].constantize
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# Derives the name of associated model from association name and
|
167
|
+
# returns its class
|
168
|
+
##
|
169
|
+
def model_from_namespace #nodoc
|
170
|
+
name = multiple? ? @name.to_s.classify : @name.to_s.pluralize.classify
|
171
|
+
# Keep this weird comparison. RDF::Vocabulary doesn't recognize `nil?` or `==`
|
172
|
+
(nil == @cls.namespace) ? nil : @cls[@cls.namespace[name]]
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# Checks if this attribute is an association with multiple objects
|
177
|
+
# (i.e. `has_many` or `has_and_belongs_to`). Used for deriving association
|
178
|
+
# name (plural / singular)
|
179
|
+
##
|
180
|
+
def multiple? #nodoc
|
181
|
+
@options[:association] == :has_many || @options[:association] == :has_and_belongs
|
182
|
+
end
|
183
|
+
|
184
|
+
end # Attribute
|
185
|
+
end # Model
|
186
|
+
end # RDFMapper
|