Class: GraphStarter::Asset
- Inherits:
-
Object
- Object
- GraphStarter::Asset
show all
- Includes:
- Authorizable, Neo4j::ActiveNode, Neo4j::Timestamps
- Defined in:
- app/models/graph_starter/asset.rb
Defined Under Namespace
Classes: SecretSauceRecommendation
Class Method Summary
collapse
Instance Method Summary
collapse
#set_access_levels
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
107
108
109
110
111
112
113
114
115
116
117
|
# File 'app/models/graph_starter/asset.rb', line 107
def method_missing(method_name, *args, &block)
if [:name, :title].include?(method_name.to_sym)
self.class.send(:define_method, method_name) do
read_attribute(self.class.name_property)
end
send(method_name)
else
super
end
end
|
Class Method Details
.authorized_associations ⇒ Object
223
224
225
|
# File 'app/models/graph_starter/asset.rb', line 223
def self.authorized_associations
associations.except(*Asset.associations.keys + [:images])
end
|
.authorized_for(user) ⇒ Object
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
# File 'app/models/graph_starter/asset.rb', line 173
def self.authorized_for(user)
require 'graph_starter/query_authorizer'
if category_association
::GraphStarter::QueryAuthorizer.new(all(:asset).send(category_association, :category, nil, optional: true))
.authorized_query([:asset, :category], user)
.with('DISTINCT asset AS asset')
.proxy_as(self, :asset)
else
::GraphStarter::QueryAuthorizer.new(all(:asset))
.authorized_query(:asset, user)
.with('DISTINCT asset AS asset')
.proxy_as(self, :asset)
end
end
|
.authorized_properties(user) ⇒ Object
189
190
191
|
# File 'app/models/graph_starter/asset.rb', line 189
def self.authorized_properties(user)
authorized_properties_query(user).pluck(:property)
end
|
.authorized_properties_and_levels(user) ⇒ Object
193
194
195
|
# File 'app/models/graph_starter/asset.rb', line 193
def self.authorized_properties_and_levels(user)
authorized_properties_query(user).pluck(:property, :level)
end
|
.authorized_properties_query(user) ⇒ Object
197
198
199
200
201
202
203
204
205
206
207
208
209
|
# File 'app/models/graph_starter/asset.rb', line 197
def self.authorized_properties_query(user)
query = property_name_and_uuid_and_ruby_type_query
.merge(model: {Model: {name: name}})
.on_create_set(model: {private: false})
.break
.merge('model-[:HAS_PROPERTY]->(property:Property {name: property_name})')
.on_create_set(property: {private: false})
.on_create_set('property.uuid = uuid, property.ruby_type = ruby_type')
.with(:property)
::GraphStarter::Property
QueryAuthorizer.new(query).authorized_query(:property, user)
end
|
.category_association(association_name = nil) ⇒ Object
46
47
48
49
50
51
52
53
54
55
|
# File 'app/models/graph_starter/asset.rb', line 46
def self.category_association(association_name = nil)
if association_name.nil?
@category_association
else
fail "Cannot declare category_association twice" if @category_association.present?
name = association_name.to_sym
fail ArgumentError, "Association #{name} is not defined" if associations[name].nil?
@category_association = name
end
end
|
.default_name_property ⇒ Object
90
91
92
93
94
95
96
|
# File 'app/models/graph_starter/asset.rb', line 90
def self.default_name_property
(%w(name title) & attributes.keys)[0].tap do |property|
if property.nil?
fail "No name_property defined for #{self.name}!"
end
end
end
|
.descendants ⇒ Object
160
161
162
163
|
# File 'app/models/graph_starter/asset.rb', line 160
def self.descendants
Rails.application.eager_load! if Rails.env == 'development'
Neo4j::ActiveNode::Labels._wrapped_classes.select { |klass| klass < self }
end
|
.for_query(query) ⇒ Object
120
121
122
|
# File 'app/models/graph_starter/asset.rb', line 120
def self.for_query(query)
all.where(title: /.*#{query}.*/i)
end
|
.has_images ⇒ Object
33
34
35
36
|
# File 'app/models/graph_starter/asset.rb', line 33
def self.has_images
@has_images = true
has_many :out, :images, type: :HAS_IMAGE, model_class: '::GraphStarter::Image'
end
|
.has_images? ⇒ Boolean
38
39
40
|
# File 'app/models/graph_starter/asset.rb', line 38
def self.has_images?
!!@has_images
end
|
.icon_class ⇒ Object
227
228
229
|
# File 'app/models/graph_starter/asset.rb', line 227
def self.icon_class
'bookmark'
end
|
.model_slug ⇒ Object
165
166
167
|
# File 'app/models/graph_starter/asset.rb', line 165
def self.model_slug
name.tableize
end
|
.name_property(property_name = nil) ⇒ Object
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'app/models/graph_starter/asset.rb', line 75
def self.name_property(property_name = nil)
if property_name.nil?
name_property(default_name_property) if @name_property.nil?
@name_property
else
fail "Cannot declare name_property twice" if @name_property.present?
name = property_name.to_sym
fail ArgumentError, "Property #{name} is not defined" if attributes[name.to_s].nil?
@name_property = name
validates name, presence: true
end
end
|
.properties ⇒ Object
169
170
171
|
# File 'app/models/graph_starter/asset.rb', line 169
def self.properties
attributes.keys - Asset.attributes.keys
end
|
.property_name_and_uuid_and_ruby_type_query ⇒ Object
211
212
213
214
215
216
217
218
219
220
221
|
# File 'app/models/graph_starter/asset.rb', line 211
def self.property_name_and_uuid_and_ruby_type_query
properties_and_uuids_and_ruby_types = properties.map do |property|
[property, SecureRandom.uuid, self.attributes[property][:type]]
end
Neo4j::Session.current.query
.with('{array} AS array')
.unwind('array AS row')
.params(array: properties_and_uuids_and_ruby_types)
.with('row[0] AS property_name, row[1] AS uuid, row[2] AS ruby_type')
end
|
.rated ⇒ Object
66
67
68
|
# File 'app/models/graph_starter/asset.rb', line 66
def self.rated
@rated = true
end
|
.rated? ⇒ Boolean
70
71
72
|
# File 'app/models/graph_starter/asset.rb', line 70
def self.rated?
!!@rated
end
|
Instance Method Details
#as_json(_options = {}) ⇒ Object
150
151
152
153
154
155
156
157
158
|
# File 'app/models/graph_starter/asset.rb', line 150
def as_json(_options = {})
{self.class.model_slug =>
{id: id,
title: title,
name: title,
images: images.map {|image| image.source.url },
model_slug: self.class.model_slug}
}
end
|
#body ⇒ Object
30
31
|
# File 'app/models/graph_starter/asset.rb', line 30
def body
end
|
#categories ⇒ Object
57
58
59
60
61
62
63
|
# File 'app/models/graph_starter/asset.rb', line 57
def categories
if self.class.category_association
send(self.class.category_association)
else
[]
end
end
|
#first_image_source_url ⇒ Object
42
43
44
|
# File 'app/models/graph_starter/asset.rb', line 42
def first_image_source_url
images.first && images.first.source_url
end
|
#name ⇒ Object
146
147
148
|
# File 'app/models/graph_starter/asset.rb', line 146
def name
title
end
|
#rating_for(user) ⇒ Object
103
104
105
|
# File 'app/models/graph_starter/asset.rb', line 103
def rating_for(user)
rated_by_user(nil, :rating).where(uuid: user.uuid).pluck(:rating)[0]
end
|
#rating_level_for(user) ⇒ Object
98
99
100
101
|
# File 'app/models/graph_starter/asset.rb', line 98
def rating_level_for(user)
rating = rating_for(user)
rating && rating.level
end
|
#secret_sauce_recommendations ⇒ Object
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
# File 'app/models/graph_starter/asset.rb', line 124
def secret_sauce_recommendations
user_class = GraphStarter.configuration.user_class
user_class = (user_class.is_a?(Class) ? user_class : user_class.to_s.constantize)
user_label = user_class.mapped_label_name
query_as(:source)
.match('source-[:HAS_CATEGORY]->(category:Category)<-[:HAS_CATEGORY]-(asset:Asset)')
.break
.optional_match("source<-[:CREATED]-(creator:#{user_label})-[:CREATED]->asset")
.break
.optional_match("source<-[:VIEWED]-(viewer:#{user_label})-[:VIEWED]->asset")
.limit(5)
.order('score DESC')
.pluck(
:asset,
'(count(category) * 2) +
(count(creator) * 4) +
(count(viewer) * 0.1) AS score').map do |other_asset, score|
SecretSauceRecommendation.new(other_asset, score)
end
end
|