abstractor 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/app/assets/stylesheets/abstractor/abstractor_abstractions.css +8 -0
- data/app/views/abstractor/abstractor_abstractions/_fields.html.haml +6 -0
- data/app/views/abstractor/abstractor_abstractions/edit.html.haml +1 -1
- data/db/migrate/20140803205149_add_custom_explanation_to_abstractor_suggestion_sources.rb +5 -0
- data/lib/abstractor/abstractable.rb +25 -4
- data/lib/abstractor/methods/controllers/abstractor_abstraction_groups_controller.rb +4 -0
- data/lib/abstractor/methods/models/abstractor_abstraction.rb +5 -2
- data/lib/abstractor/methods/models/abstractor_subject.rb +23 -17
- data/lib/abstractor/methods/models/abstractor_suggestion_source.rb +1 -1
- data/lib/abstractor/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWUzYjczYWRlYjNkMzRiNzc2YTRjYjQ3YjIyM2IyZDAwYjE2ZGNkZg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDczMzEzODRiNGE1ZjM5NmYyYmQxM2Q1ODUyOGQ5NGQ2N2Y4MjY4Yw==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTRlNzg5ZDFiOTlhMDBmMDc4YmNhZDkyYTY1Nzc0YjU0ZmEzYWJmYmY1YzEz
|
10
|
+
OGRkMGE2MTkwZDUzNTcxODRjZjcwYTI4ODlmN2NlMzExN2U4YjBiNzM0ZTI0
|
11
|
+
MzFlMTkzOWU2NDc4MWZkOTBhYmMzMDJkZmZiYzBhMWI2MTg4OWI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NGY1YTAzNmZiYWU4NWUxZThiOTExZmQxYWMyYjcwYTVkNTVkZTQzZThjMzc1
|
14
|
+
MTAxYmFkNmYzMjQ3ZjUyOGYyMWFhZTgzODAyMWI3OWIwMDJmYWY3ZjE0N2Fi
|
15
|
+
NTZhOWJjNjVmMDgzN2QxYzEyZDA3NmRmZjc4YmE5ODRiMWNjYzI=
|
@@ -330,4 +330,12 @@ span.tooltip_img {
|
|
330
330
|
|
331
331
|
.indirect_source {
|
332
332
|
margin-bottom: 1em;
|
333
|
+
}
|
334
|
+
|
335
|
+
.abstractor_suggestion_values .custom_explanation {
|
336
|
+
margin-top: .5em;
|
337
|
+
}
|
338
|
+
|
339
|
+
.abstractor_suggestion_values .custom_explanation label {
|
340
|
+
font-weight: bold !important;
|
333
341
|
}
|
@@ -47,6 +47,12 @@
|
|
47
47
|
= Abstractor::UserInterface.highlight(simple_format(abstractable_from_column.clone), abstractor_suggestion_source.sentence_match_value.strip)
|
48
48
|
- else
|
49
49
|
= simple_format(abstractable_from_column.clone)
|
50
|
+
- if abstractor_suggestion_source.custom_explanation
|
51
|
+
.custom_explanation
|
52
|
+
%label
|
53
|
+
Explanation:
|
54
|
+
.explanation_text
|
55
|
+
= abstractor_suggestion_source.custom_explanation
|
50
56
|
.column-3
|
51
57
|
- values = Abstractor::AbstractorSuggestionStatus.all.sort_by(&:name).map{|s| [s.name, s.id] }
|
52
58
|
- values.each do |value|
|
@@ -43,7 +43,7 @@
|
|
43
43
|
= f.label :unknown, 'unknown'
|
44
44
|
.column-3
|
45
45
|
- abstractor_abstraction = f.object
|
46
|
-
- abstraction_sources = abstractor_abstraction.abstractor_subject.abstractor_abstraction_sources.select { |s| s.abstractor_abstraction_source_type.name
|
46
|
+
- abstraction_sources = abstractor_abstraction.abstractor_subject.abstractor_abstraction_sources.select { |s| s.abstractor_abstraction_source_type.name != 'indirect' }
|
47
47
|
- abstraction_sources.each do |abstraction_source|
|
48
48
|
- abstraction_source.normalize_from_method_to_sources(abstractor_abstraction.about).each do |source|
|
49
49
|
- dom_id = "#{abstraction_source.id}_#{source[:source_type]}_#{source[:source_id]}_#{source[:source_method]}"
|
@@ -49,10 +49,28 @@ module Abstractor
|
|
49
49
|
abstractor_abstraction_group
|
50
50
|
end
|
51
51
|
|
52
|
-
|
53
|
-
|
52
|
+
##
|
53
|
+
# Returns all abstraction for the abstractable entity by abstractor_abstraction_status:
|
54
|
+
#
|
55
|
+
# * 'needs_review': Filter abstractions without a determined value (value, unknown or not_applicable).
|
56
|
+
# * 'reviewed': Filter abstractions having a determined value (value, unknown or not_applicable).
|
57
|
+
#
|
58
|
+
# @param [String] abstractor_abstraction_status Filter abstractions that need review or are reviews.
|
59
|
+
# @return [ActiveRecord::Relation] List of [Abstractor::AbstractorAbstraction].
|
60
|
+
def abstractor_abstractions_by_abstractor_abstraction_status(abstractor_abstraction_status)
|
61
|
+
case abstractor_abstraction_status
|
62
|
+
when 'needs_review'
|
63
|
+
abstractor_abstractions.select { |abstractor_abstraction| abstractor_abstraction.value.blank? && abstractor_abstraction.unknown.blank? && abstractor_abstraction.not_applicable.blank? }
|
64
|
+
when 'reviewed'
|
65
|
+
abstractor_abstractions.select { |abstractor_abstraction| !abstractor_abstraction.value.blank? || !abstractor_abstraction.unknown.blank? || !abstractor_abstraction.not_applicable.blank? }
|
66
|
+
end
|
54
67
|
end
|
55
68
|
|
69
|
+
##
|
70
|
+
# Removes all abstractions, suggestions and indirect sources for the abstractable entity. Optionally filtred to only 'unreviewd' abstractions.
|
71
|
+
#
|
72
|
+
# @param [Boolean] only_unreviewed Instructs whther to confine removal to only 'unreviewd' abstractions.
|
73
|
+
# @return [void]
|
56
74
|
def remove_abstractions(only_unreviewed = true)
|
57
75
|
abstractor_abstractions.each do |abstractor_abstraction|
|
58
76
|
if !only_unreviewed || (only_unreviewed && abstractor_abstraction.unreviewed?)
|
@@ -61,6 +79,9 @@ module Abstractor
|
|
61
79
|
abstractor_suggestion.abstractor_suggestion_object_value.destroy if abstractor_suggestion.abstractor_suggestion_object_value
|
62
80
|
abstractor_suggestion.destroy
|
63
81
|
end
|
82
|
+
abstractor_abstraction.abstractor_indirect_sources.each do |abstractor_indirect_source|
|
83
|
+
abstractor_indirect_source.destroy
|
84
|
+
end
|
64
85
|
abstractor_abstraction.destroy
|
65
86
|
end
|
66
87
|
end
|
@@ -79,9 +100,9 @@ module Abstractor
|
|
79
100
|
def by_abstractor_abstraction_status(abstractor_abstraction_status)
|
80
101
|
case abstractor_abstraction_status
|
81
102
|
when 'needs_review'
|
82
|
-
where(["EXISTS (SELECT 1 FROM
|
103
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND (aa.value IS NULL OR aa.value = '') AND (aa.unknown IS NULL OR aa.unknown = ?) AND (aa.not_applicable IS NULL OR aa.not_applicable = ?))", false, false])
|
83
104
|
when 'reviewed'
|
84
|
-
where(["EXISTS (SELECT 1 FROM
|
105
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id) AND NOT EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id AND COALESCE(aa.value, '') = '' AND COALESCE(aa.unknown, ?) != ? AND COALESCE(aa.not_applicable, ?) != ?)", false, true, false, true])
|
85
106
|
else
|
86
107
|
where(nil)
|
87
108
|
end
|
@@ -12,6 +12,10 @@ module Abstractor
|
|
12
12
|
@abstractor_abstraction_group.abstractor_subject_group.abstractor_subjects.each do |abstractor_subject|
|
13
13
|
abstraction = abstractor_subject.abstractor_abstractions.build(about_id: params[:about_id], about_type: params[:about_type])
|
14
14
|
abstraction.build_abstractor_abstraction_group_member(abstractor_abstraction_group: @abstractor_abstraction_group)
|
15
|
+
abstraction.abstractor_subject.abstractor_abstraction_sources.select { |s| s.abstractor_abstraction_source_type.name == 'indirect' }.each do |abstractor_abstraction_source|
|
16
|
+
source = abstractor_subject.subject_type.constantize.find(params[:about_id]).send(abstractor_abstraction_source.from_method)
|
17
|
+
abstraction.abstractor_indirect_sources.build(abstractor_abstraction_source: abstractor_abstraction_source, source_type: source[:source_type], source_method: source[:source_method])
|
18
|
+
end
|
15
19
|
abstraction.save!
|
16
20
|
end
|
17
21
|
|
@@ -66,9 +66,12 @@ module Abstractor
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
+
##
|
70
|
+
# Determines if the abstraction has been reviewed.
|
71
|
+
#
|
72
|
+
# @return [Boolean]
|
69
73
|
def unreviewed?
|
70
|
-
|
71
|
-
abstractor_suggestions.any? { |abstractor_suggestion| abstractor_suggestion.abstractor_suggestion_status == abstractor_suggestion_status_needs_review }
|
74
|
+
(value.blank? && unknown.blank? && not_applicable.blank?)
|
72
75
|
end
|
73
76
|
|
74
77
|
##
|
@@ -64,7 +64,7 @@ module Abstractor
|
|
64
64
|
# method on the abstractable enttiy specified in Abstractor::AbstractorAbstractionSource#from_method.
|
65
65
|
# The method should return a hash with the following keys populated:
|
66
66
|
#
|
67
|
-
# * [Array<ActiveRecord::Base>] :sources An array of active record objects that constitute the list of indirect sources.
|
67
|
+
# * [Array <ActiveRecord::Base>] :sources An array of active record objects that constitute the list of indirect sources.
|
68
68
|
# * [Symbol] :source_id A method specifying the primary key of each member in sources.
|
69
69
|
# * [Symbol] :source_method A method specifying the source text of each member in sources.
|
70
70
|
#
|
@@ -94,7 +94,6 @@ module Abstractor
|
|
94
94
|
# @param [Abstractor::AbstractorAbstraction] abstractor_abstraction The instance of Abstractor::AbstractorAbstraction to make suggestions against.
|
95
95
|
# @param [Abstractor::AbstractorAbstractionSource] abstractor_abstraction_source The instance of the Abstractor::AbstractorAbstractionSource that provides the rule type and from method to make nlp suggestions.
|
96
96
|
# @return [void]
|
97
|
-
|
98
97
|
def abstract_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
|
99
98
|
case abstractor_abstraction_source.abstractor_rule_type.name
|
100
99
|
when 'name/value'
|
@@ -107,24 +106,30 @@ module Abstractor
|
|
107
106
|
end
|
108
107
|
|
109
108
|
# Creates instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource
|
110
|
-
# based on calling the method
|
109
|
+
# based on calling the method configured by the AbstractorAbstractionSource#custom_method attribute.
|
111
110
|
# The method is called on the abstractable entity passed via the about parameter.
|
112
111
|
#
|
113
112
|
# Setting up an Abstractor::AbstractorSubject with an AbstractorAbstractionSource
|
114
113
|
# with an AbstractorAbstractionSource#abstractor_abstraction_source_type attribute
|
115
114
|
# set to 'custom suggestion' obligates the developer to implement an instance
|
116
|
-
# method on the abstractable entitty to make suggestions as
|
117
|
-
#
|
118
|
-
#
|
115
|
+
# method on the abstractable entitty to make suggestions as appropriate.
|
116
|
+
# The 'custom suggestion' source type is intended to faciliate the
|
117
|
+
# generation of suggestions in a customizable way. The method implemented
|
118
|
+
# by the developer should return an array of hashes, each has with 2 keys, like so
|
119
|
+
#
|
120
|
+
# [{ suggestion: 'a suggestion', explanation: 'why i made the suggestion}]
|
119
121
|
#
|
122
|
+
# The suggestion will be presented to the user as possible answer for the
|
123
|
+
# abstraction. The explanation will be displayed to the user to explain
|
124
|
+
# how the sytem arrived at the suggestion.
|
120
125
|
# @param [ActiveRecord::Base] about The entity to abstract. An instance of the class specified in the Abstractor::AbstractorSubject#subject_type attribute.
|
121
126
|
# @param [Abstractor::AbstractorAbstraction] abstractor_abstraction The instance of Abstractor::AbstractorAbstraction to make suggestions against.
|
122
127
|
# @param [Abstractor::AbstractorAbstractionSource] abstractor_abstraction_source The instance of the Abstractor::AbstractorAbstractionSource that provides the custom method to invoke on the abstractable entity to make custom suggestions.
|
123
128
|
# @return [void]
|
124
129
|
def abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
|
125
|
-
|
126
|
-
|
127
|
-
suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, about.id, about.class.to_s, abstractor_abstraction_source.from_method,
|
130
|
+
suggestions = about.send(abstractor_abstraction_source.custom_method)
|
131
|
+
suggestions.each do |suggestion|
|
132
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, about.id, about.class.to_s, abstractor_abstraction_source.from_method, suggestion[:suggestion], nil, nil, abstractor_abstraction_source.custom_method, suggestion[:explanation])
|
128
133
|
end
|
129
134
|
create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
|
130
135
|
end
|
@@ -179,7 +184,7 @@ module Abstractor
|
|
179
184
|
Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], object_variant)
|
180
185
|
)
|
181
186
|
if !reject
|
182
|
-
suggest(abstractor_abstraction, abstractor_abstraction_source, object_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], abstractor_object_value, nil, nil, nil)
|
187
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, object_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], abstractor_object_value, nil, nil, nil, nil)
|
183
188
|
end
|
184
189
|
end
|
185
190
|
end
|
@@ -206,13 +211,13 @@ module Abstractor
|
|
206
211
|
match_value = "#{Regexp.escape(predicate_variant)}:\s*#{Regexp.escape(object_variant)}"
|
207
212
|
matches = parser.scan(match_value, word_boundary: true).uniq
|
208
213
|
matches.each do |match|
|
209
|
-
suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], abstractor_object_value, nil, nil, nil)
|
214
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], abstractor_object_value, nil, nil, nil, nil)
|
210
215
|
end
|
211
216
|
|
212
217
|
match_value = "#{Regexp.escape(predicate_variant)}#{Regexp.escape(object_variant)}"
|
213
218
|
matches = parser.scan(match_value, word_boundary: true).uniq
|
214
219
|
matches.each do |match|
|
215
|
-
suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], abstractor_object_value, nil, nil, nil)
|
220
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], abstractor_object_value, nil, nil, nil, nil)
|
216
221
|
end
|
217
222
|
end
|
218
223
|
end
|
@@ -242,7 +247,7 @@ module Abstractor
|
|
242
247
|
Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], object_variant)
|
243
248
|
)
|
244
249
|
if !reject
|
245
|
-
suggest(abstractor_abstraction, abstractor_abstraction_source, sentence[:sentence], sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], abstractor_object_value, nil, nil, nil)
|
250
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, sentence[:sentence], sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], abstractor_object_value, nil, nil, nil, nil)
|
246
251
|
end
|
247
252
|
end
|
248
253
|
end
|
@@ -254,7 +259,7 @@ module Abstractor
|
|
254
259
|
end
|
255
260
|
end
|
256
261
|
|
257
|
-
def suggest(abstractor_abstraction, abstractor_abstraction_source, match_value, sentence_match_value, source_id, source_type, source_method, suggested_value, unknown, not_applicable, custom_method)
|
262
|
+
def suggest(abstractor_abstraction, abstractor_abstraction_source, match_value, sentence_match_value, source_id, source_type, source_method, suggested_value, unknown, not_applicable, custom_method, custom_explanation)
|
258
263
|
match_value.strip! unless match_value.nil?
|
259
264
|
sentence_match_value.strip! unless sentence_match_value.nil?
|
260
265
|
if abstractor_object_value?(suggested_value)
|
@@ -285,7 +290,8 @@ module Abstractor
|
|
285
290
|
source_id: source_id,
|
286
291
|
source_type: source_type,
|
287
292
|
source_method: source_method,
|
288
|
-
custom_method: custom_method
|
293
|
+
custom_method: custom_method,
|
294
|
+
custom_explanation: custom_explanation
|
289
295
|
)
|
290
296
|
end
|
291
297
|
abstractor_suggestion
|
@@ -313,7 +319,7 @@ module Abstractor
|
|
313
319
|
Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], predicate_variant)
|
314
320
|
)
|
315
321
|
if !reject
|
316
|
-
suggest(abstractor_abstraction, abstractor_abstraction_source, predicate_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], nil, true, nil, nil)
|
322
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, predicate_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], nil, true, nil, nil, nil)
|
317
323
|
end
|
318
324
|
end
|
319
325
|
end
|
@@ -327,7 +333,7 @@ module Abstractor
|
|
327
333
|
#Create an 'unknown' suggestion based on matching nothing only if we have not made a suggstion
|
328
334
|
abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
|
329
335
|
if abstractor_abstraction.abstractor_suggestions(true).empty?
|
330
|
-
suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, source[:source_id], source[:source_type].to_s, source[:source_method], nil, true, nil, nil)
|
336
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, source[:source_id], source[:source_type].to_s, source[:source_method], nil, true, nil, nil, nil)
|
331
337
|
end
|
332
338
|
end
|
333
339
|
end
|
@@ -9,7 +9,7 @@ module Abstractor
|
|
9
9
|
base.send :belongs_to, :abstractor_abstraction_source
|
10
10
|
base.send :belongs_to, :abstractor_suggestion
|
11
11
|
|
12
|
-
base.send :attr_accessible, :abstractor_abstraction_source, :abstractor_abstraction_source_id, :abstractor_suggestion, :abstractor_suggestion_id, :source_id, :source_type, :source_method, :match_value, :deleted_at, :sentence_match_value, :custom_method
|
12
|
+
base.send :attr_accessible, :abstractor_abstraction_source, :abstractor_abstraction_source_id, :abstractor_suggestion, :abstractor_suggestion_id, :source_id, :source_type, :source_method, :match_value, :deleted_at, :sentence_match_value, :custom_method, :custom_explanation
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/lib/abstractor/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: abstractor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Gurley, Yulia Bushmanova
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -487,6 +487,7 @@ files:
|
|
487
487
|
- db/migrate/20140618140828_add_custom_method_to_abstractor_suggestion_sources.rb
|
488
488
|
- db/migrate/20140716184049_add_dynamic_list_method_to_abstractor_subjects.rb
|
489
489
|
- db/migrate/20140718014952_refactor_abstractor_rule_types.rb
|
490
|
+
- db/migrate/20140803205149_add_custom_explanation_to_abstractor_suggestion_sources.rb
|
490
491
|
- db/seeds.rb
|
491
492
|
- lib/abstractor.rb
|
492
493
|
- lib/abstractor/abstractable.rb
|