abstractor 2.0.1 → 2.1.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.
- 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
|