abstractor 2.1.2 → 4.0.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/README.md +9 -6
- data/app/assets/javascripts/abstractor/abstractor.js.coffee +115 -0
- data/app/assets/javascripts/abstractor/application.js +0 -8
- data/app/assets/stylesheets/abstractor/abstractor_abstractions.css +21 -1
- data/app/views/abstractor/abstractor_abstraction_groups/_form.html.haml +3 -3
- data/app/views/abstractor/abstractor_abstractions/_fields.html.haml +15 -5
- data/app/views/abstractor/abstractor_abstractions/_list.html.haml +9 -13
- data/app/views/abstractor/abstractor_abstractions/edit.html.haml +3 -3
- data/db/migrate/20140816005228_add_namespace_to_abstractor_subjects.rb +6 -0
- data/lib/abstractor/abstractable.rb +228 -87
- data/lib/abstractor/enum.rb +4 -0
- data/lib/abstractor/methods/controllers/abstractor_abstractions_controller.rb +7 -1
- data/lib/abstractor/methods/controllers/abstractor_suggestions_controller.rb +6 -2
- data/lib/abstractor/methods/models/abstractor_abstraction.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_group.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_group_member.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_schema.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_schema_object_value.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_schema_predicate_variant.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_schema_relation.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_source.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_abstraction_source_type.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_indirect_source.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_object_type.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_object_value.rb +1 -2
- data/lib/abstractor/methods/models/abstractor_object_value_variant.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_relation_type.rb +2 -1
- data/lib/abstractor/methods/models/abstractor_rule_type.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_subject.rb +22 -18
- data/lib/abstractor/methods/models/abstractor_subject_group.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_subject_group_member.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_subject_relation.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_suggestion.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_suggestion_object_value.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_suggestion_source.rb +1 -1
- data/lib/abstractor/methods/models/abstractor_suggestion_status.rb +1 -1
- data/lib/abstractor/negation_detection.rb +1 -1
- data/lib/abstractor/setup.rb +18 -18
- data/lib/abstractor/version.rb +1 -1
- data/lib/generators/abstractor/install/install_generator.rb +1 -1
- metadata +54 -34
- data/app/assets/javascripts/abstractor/abstractor.js +0 -108
- data/app/assets/javascripts/abstractor/nested_attributes.js +0 -69
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjcxMTgwOGI0Y2QwNDNjMjc4NDE2Y2I0YmIwYWQ2ZTg5YzU0NjI2Zg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTJmNWM0ZTcwMzZmMzk5YTRjYjBiMWU5Y2JkZWI1NTFkZjc5NGU1NA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjE5NjUwNDVjNDcwMGVlZWEwNjM3MDQ2ODI5NzdiOTExNjZjZjY0Y2RmNzc5
|
10
|
+
NjcwMjljNDg4YmU2MDkwMmUxNjk2MTg0MWQ4NTM0OTlkZWUxMjc3YTI2Mzk1
|
11
|
+
YjE4NmIyODlkMjRhMDYwZGQ1NTgwMDg0NGYwMWM4OTExMmNlODg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MTNmMjNjZDQ1OGNmM2U5MGFhODFlNWZjNDZkOWVlODE5OWZiYjMwNDAwYjU0
|
14
|
+
OTFjZTI5MjQ5OGZmYWZlNzczZDVhMThmMzEwN2QxMWYxZWJjMGI4YWY2ZTEx
|
15
|
+
OTJiMDdiMzM2YTVhZTdkMzNkNmNkMGRjYTM4ZTA5MWJmZWI4MmI=
|
data/README.md
CHANGED
@@ -5,10 +5,6 @@ from narrative text via natural language processing. The gem includes
|
|
5
5
|
a user interface to present the abstracted data points for
|
6
6
|
confirmation/revision by a curator.
|
7
7
|
|
8
|
-
Reader's note: this README uses [YARD][] markup to provide links to
|
9
|
-
Abstractor's API documentation. If you aren't already, consider reading it
|
10
|
-
on [rubydoc.info][] so that the links will be followable.
|
11
|
-
|
12
8
|
[YARD]: http://yardoc.org/
|
13
9
|
[rubydoc.info]: http://rubydoc.info/github/NUBIC/abstractor/master/file/README.md
|
14
10
|
|
@@ -20,7 +16,9 @@ on [rubydoc.info][] so that the links will be followable.
|
|
20
16
|
Abstractor works with:
|
21
17
|
|
22
18
|
* Ruby 1.9.3, 2.0.0 and 2.1.1
|
23
|
-
*
|
19
|
+
* >= Rails 4.1
|
20
|
+
* Rails 3.2 branch now available [here][]
|
21
|
+
[here]: https://github.com/NUBIC/abstractor/tree/rails-3
|
24
22
|
|
25
23
|
Some key dependencies are:
|
26
24
|
|
@@ -47,11 +45,16 @@ Add abstractor to your Gemfile:
|
|
47
45
|
```ruby
|
48
46
|
gem 'abstractor'
|
49
47
|
```
|
48
|
+
or if using Rails 3
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
gem 'abstractor', :git => 'https://github.com/NUBIC/abstractor', branch: 'rails-3'
|
52
|
+
```
|
50
53
|
|
51
54
|
Add the stanford-core-nlp gem to your Gemfile. Currently need to use the master branch of the official repository until a new version of the gem is released:
|
52
55
|
|
53
56
|
```ruby
|
54
|
-
gem 'stanford-core-nlp', :git => 'https://github.com/louismullie/stanford-core-nlp', :
|
57
|
+
gem 'stanford-core-nlp', :git => 'https://github.com/louismullie/stanford-core-nlp', branch: 'master'
|
55
58
|
```
|
56
59
|
|
57
60
|
Also add the paper\_trail gem to your Gemfile (if it is not already there):
|
@@ -0,0 +1,115 @@
|
|
1
|
+
Abstractor = {}
|
2
|
+
Abstractor.AbstractionUI = ->
|
3
|
+
$(document).on "click", ".abstractor_abstraction_value a.edit_link", (e) ->
|
4
|
+
e.preventDefault()
|
5
|
+
parent_div = $(this).closest(".abstractor_abstraction")
|
6
|
+
parent_div.load $(this).attr("href"), ->
|
7
|
+
parent_div.find(".combobox").combobox watermark: "a value"
|
8
|
+
$(".abstractor_datepicker").datepicker
|
9
|
+
altFormat: "yy-mm-dd"
|
10
|
+
dateFormat: "yy-mm-dd"
|
11
|
+
changeMonth: true
|
12
|
+
changeYear: true
|
13
|
+
|
14
|
+
return
|
15
|
+
|
16
|
+
parent_div.addClass "highlighted"
|
17
|
+
return
|
18
|
+
|
19
|
+
$(document).on "ajax:success", "form.edit_abstractor_abstraction", (e, data, status, xhr) ->
|
20
|
+
parent_div = $(this).closest(".abstractor_abstraction")
|
21
|
+
parent_div.html xhr.responseText
|
22
|
+
|
23
|
+
parent_div.removeClass "highlighted"
|
24
|
+
return
|
25
|
+
|
26
|
+
$(document).on "click", ".edit_abstractor_abstraction input[type='radio']", ->
|
27
|
+
$(this).siblings("input[type='checkbox']").prop "checked", false
|
28
|
+
return
|
29
|
+
|
30
|
+
$(document).on "click", ".edit_abstractor_abstraction input[type='checkbox']", ->
|
31
|
+
$(this).siblings("input[type='checkbox']").prop "checked", false
|
32
|
+
$(this).siblings("input[type='text']").prop "value", ""
|
33
|
+
autocompleters = $(this).siblings("select.combobox")
|
34
|
+
autocompleters.combobox "setValue", ""
|
35
|
+
autocompleters.change()
|
36
|
+
$.each $(this).siblings("input[type='radio']"), ->
|
37
|
+
if $(this).prop("value") is ""
|
38
|
+
$(this).prop "checked", true
|
39
|
+
else
|
40
|
+
$(this).prop "checked", false
|
41
|
+
return
|
42
|
+
|
43
|
+
return
|
44
|
+
|
45
|
+
$(document).on "change", ".edit_abstractor_abstraction select.combobox", ->
|
46
|
+
$(this).siblings("input[type='checkbox']").prop "checked", false if $(this).find("option:selected").prop("value").length
|
47
|
+
return
|
48
|
+
|
49
|
+
$(document).on "change", ".edit_abstractor_abstraction input[type='text']", ->
|
50
|
+
$(this).siblings("input[type='checkbox']").prop "checked", false
|
51
|
+
return
|
52
|
+
|
53
|
+
$(document).on "click", ".abstractor_abstraction_source_tooltip_img", (evt) ->
|
54
|
+
target = $(this).attr("rel")
|
55
|
+
html = $(target).html()
|
56
|
+
title = $(this).attr("title")
|
57
|
+
evt.preventDefault()
|
58
|
+
$("#abstractor_abstraction_dialog_tooltip").dialog
|
59
|
+
maxHeight: 400
|
60
|
+
autoOpen: false
|
61
|
+
width: 600
|
62
|
+
zIndex: 40000
|
63
|
+
dialogClass: "ui-dialog_abstractor"
|
64
|
+
$("#abstractor_abstraction_dialog_tooltip").html html
|
65
|
+
$("#abstractor_abstraction_dialog_tooltip").dialog "option", "title", title
|
66
|
+
$("#abstractor_abstraction_dialog_tooltip").dialog "option", "width", ($(window).width() * 0.80)
|
67
|
+
$("#abstractor_abstraction_dialog_tooltip").dialog "open"
|
68
|
+
return
|
69
|
+
|
70
|
+
$(document).on "change", "select.indirect_source_list", ->
|
71
|
+
source_type = $(this).attr("rel")
|
72
|
+
value = $(this).find("option:selected").prop("value")
|
73
|
+
$(this).siblings(".indirect_source_text").addClass "hidden"
|
74
|
+
$(this).siblings("." + source_type + "_" + value).removeClass "hidden"
|
75
|
+
return
|
76
|
+
|
77
|
+
return
|
78
|
+
|
79
|
+
Abstractor.AbstractionSuggestionUI = ->
|
80
|
+
$(document).on "change", ".abstractor_suggestion_status_selection", ->
|
81
|
+
$(this).closest("form").submit()
|
82
|
+
return
|
83
|
+
|
84
|
+
$(document).on "ajax:success", "form.edit_abstractor_suggestion", (e, data, status, xhr) ->
|
85
|
+
$(this).closest(".abstractor_abstraction").html xhr.responseText
|
86
|
+
return
|
87
|
+
|
88
|
+
return
|
89
|
+
|
90
|
+
Abstractor.AbstractionGroupUI = ->
|
91
|
+
$(document).on "ajax:success", ".abstractor_abstraction_group .abstractor_group_delete_link", (e, data, status, xhr) ->
|
92
|
+
parent_div = $(this).closest(".abstractor_abstraction_group")
|
93
|
+
parent_div.html xhr.responseText
|
94
|
+
return
|
95
|
+
|
96
|
+
$(document).on "ajax:success", ".abstractor_subject_groups_container .abstractor_group_add_link", (e, data, status, xhr) ->
|
97
|
+
parent_div = $(this).closest(".abstractor_subject_groups_container")
|
98
|
+
parent_div.find(".abstractor_subject_groups").append xhr.responseText
|
99
|
+
return
|
100
|
+
|
101
|
+
$(document).on "ajax:success", ".abstractor_abstraction_group .abstractor_group_not_applicable_all_link", (e, data, status, xhr) ->
|
102
|
+
parent_div = $(this).closest(".abstractor_abstraction_group")
|
103
|
+
parent_div.html xhr.responseText
|
104
|
+
return
|
105
|
+
|
106
|
+
$(document).on "ajax:success", ".abstractor_abstraction_group .abstractor_group_unknown_all_link", (e, data, status, xhr) ->
|
107
|
+
parent_div = $(this).closest(".abstractor_abstraction_group")
|
108
|
+
parent_div.html xhr.responseText
|
109
|
+
return
|
110
|
+
|
111
|
+
return
|
112
|
+
|
113
|
+
new Abstractor.AbstractionUI()
|
114
|
+
new Abstractor.AbstractionSuggestionUI()
|
115
|
+
new Abstractor.AbstractionGroupUI()
|
@@ -10,12 +10,4 @@
|
|
10
10
|
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
11
|
// GO AFTER THE REQUIRES BELOW.
|
12
12
|
//
|
13
|
-
//= require jquery
|
14
|
-
//= require jquery_ujs
|
15
|
-
//= require jquery.ui.widget
|
16
|
-
//= require jquery.ui.autocomplete
|
17
|
-
//= require jquery.ui.datepicker
|
18
|
-
//= require jquery.ui.button
|
19
|
-
//= require jquery.ui.dialog
|
20
|
-
|
21
13
|
//= require_tree .
|
@@ -207,8 +207,27 @@
|
|
207
207
|
margin-bottom: 0.5em;
|
208
208
|
}
|
209
209
|
|
210
|
+
.abstractor_abstractions fieldset .abstractor_abstraction_value .version {
|
211
|
+
margin-top: .5em;
|
212
|
+
margin-bottom: .5em;
|
213
|
+
border-bottom: 1px #969696 dashed;
|
214
|
+
}
|
215
|
+
|
216
|
+
.abstractor_abstractions fieldset .abstractor_abstraction_value .version .version_date {
|
217
|
+
margin-bottom: .5em;
|
218
|
+
}
|
219
|
+
|
220
|
+
.abstractor_abstractions fieldset .abstractor_abstraction_value .version .version_value {
|
221
|
+
margin-bottom: .5em;
|
222
|
+
}
|
223
|
+
|
224
|
+
.abstractor_abstractions fieldset .abstractor_abstraction_value .version .version_user {
|
225
|
+
margin-bottom: .5em;
|
226
|
+
}
|
227
|
+
|
210
228
|
.abstractor_abstractions fieldset .editable_abstraction {
|
211
229
|
border-bottom: 1px #969696 dashed;
|
230
|
+
margin-right: .5em;
|
212
231
|
}
|
213
232
|
|
214
233
|
.abstractor_abstractions fieldset .abstractor_abstraction_source_tooltip_img img {
|
@@ -321,7 +340,8 @@ span.tooltip_img {
|
|
321
340
|
}
|
322
341
|
|
323
342
|
.indirect_source_list {
|
324
|
-
width:
|
343
|
+
width: 50%;
|
344
|
+
height: auto;
|
325
345
|
}
|
326
346
|
|
327
347
|
.indirect_source_text {
|
@@ -6,8 +6,8 @@
|
|
6
6
|
= render :partial => 'abstractor/abstractor_abstractions/fields', :locals => {:abstractor_abstraction => abstractor_abstraction}
|
7
7
|
|
8
8
|
.abstractor_abstraction_actions
|
9
|
-
= link_to 'Not applicable group ', Abstractor::UserInterface.abstractor_relative_path(abstractor.abstractor_abstraction_group_path(abstractor_abstraction_group, abstractor_abstraction_value: 'not applicable')), :confirm
|
10
|
-
= link_to 'Unknown group ', Abstractor::UserInterface.abstractor_relative_path(abstractor.abstractor_abstraction_group_path(abstractor_abstraction_group, abstractor_abstraction_value: 'unknown')), :confirm
|
9
|
+
= link_to 'Not applicable group ', Abstractor::UserInterface.abstractor_relative_path(abstractor.abstractor_abstraction_group_path(abstractor_abstraction_group, abstractor_abstraction_value: 'not applicable')), data: { confirm: 'Are you sure?'} , method: :put, class: "abstractor_group_not_applicable_all_link", remote: true
|
10
|
+
= link_to 'Unknown group ', Abstractor::UserInterface.abstractor_relative_path(abstractor.abstractor_abstraction_group_path(abstractor_abstraction_group, abstractor_abstraction_value: 'unknown')), data: { confirm: 'Are you sure?'}, method: :put, class: 'abstractor_group_unknown_all_link', remote: true
|
11
11
|
- if abstractor_abstraction_group.removable?
|
12
|
-
= link_to 'Delete group', Abstractor::UserInterface.abstractor_relative_path(abstractor.abstractor_abstraction_group_path(abstractor_abstraction_group)), :confirm
|
12
|
+
= link_to 'Delete group', Abstractor::UserInterface.abstractor_relative_path(abstractor.abstractor_abstraction_group_path(abstractor_abstraction_group)), data: { confirm: 'Are you sure?'}, method: :delete, class: "abstractor_group_delete_link", remote: true
|
13
13
|
%hr
|
@@ -22,9 +22,19 @@
|
|
22
22
|
%br
|
23
23
|
%b History:
|
24
24
|
- versions.each do |version|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
.version
|
26
|
+
.version_date
|
27
|
+
%i
|
28
|
+
Date:
|
29
|
+
= "#{version.created_at.to_date.to_s(:date)}"
|
30
|
+
.version_value
|
31
|
+
%i
|
32
|
+
Value:
|
33
|
+
= "#{version.reify.display_value}"
|
34
|
+
.version_user
|
35
|
+
%i
|
36
|
+
User:
|
37
|
+
= "#{version.originator}"
|
28
38
|
- if abstractor_suggestions.any?
|
29
39
|
.column-9
|
30
40
|
- abstractor_suggestions.each do |abstractor_suggestion|
|
@@ -38,7 +48,7 @@
|
|
38
48
|
- source_about = abstractor_suggestion_source.source_type.constantize.find(abstractor_suggestion_source.source_id)
|
39
49
|
- from_method = abstractor_suggestion_source.source_method
|
40
50
|
- if from_method && source_about.respond_to?(from_method)
|
41
|
-
%span{ :class => 'abstractor_abstraction_source_tooltip_img
|
51
|
+
%span{ :class => 'abstractor_abstraction_source_tooltip_img', :rel => "#abstraction_text_#{abstractor_suggestion_source.id}", :title => "#{source_about.class.to_s} #{from_method}"}
|
42
52
|
= image_tag('abstractor/page.png', :id => "abstraction_text_link_#{abstractor_suggestion_source.id}")
|
43
53
|
%div{ :id => "abstraction_text_#{abstractor_suggestion_source.id}", :class => 'abstractor_abstraction_source_tooltip'}
|
44
54
|
- abstractable_from_column = source_about.send(from_method)
|
@@ -67,7 +77,7 @@
|
|
67
77
|
- abstractor_abstraction.abstractor_subject.abstractor_abstraction_sources.select { |s| s.abstractor_abstraction_source_type.name == 'nlp suggestion' }.each do |abstractor_abstraction_source|
|
68
78
|
- abstractor_abstraction_source.normalize_from_method_to_sources(abstractor_abstraction.about).each do |source|
|
69
79
|
- dom_id = "#{abstractor_abstraction_source.id}_#{source[:source_type]}_#{source[:source_id]}_#{source[:source_method]}"
|
70
|
-
%span{ :class => 'abstractor_abstraction_source_tooltip_img
|
80
|
+
%span{ :class => 'abstractor_abstraction_source_tooltip_img', :rel =>"#abstraction_text_#{dom_id}", :title => "#{source[:source_type].to_s} #{source[:source_method]}"}
|
71
81
|
= image_tag('abstractor/page.png', :id => "abstraction_text_link_#{dom_id}")
|
72
82
|
%br
|
73
83
|
%div{ :id => "abstraction_text_#{dom_id}", :class => 'tooltip'}
|
@@ -1,8 +1,10 @@
|
|
1
1
|
- about ||= @about
|
2
|
+
- namespace_type ||= @namespace_type
|
3
|
+
- namespace_id ||= @namespace_id
|
2
4
|
.abstractor_abstractions
|
3
|
-
= link_to 'Not applicable all', Abstractor::UserInterface.abstractor_relative_path(abstractor.update_all_abstractor_abstractions_path(about_type: about.class, about_id: about.id, abstractor_abstraction_value: 'not applicable')), :confirm
|
4
|
-
= link_to 'Unknown all', Abstractor::UserInterface.abstractor_relative_path(abstractor.update_all_abstractor_abstractions_path(about_type: about.class, about_id: about.id, abstractor_abstraction_value: 'unknown')), :confirm
|
5
|
-
- abstractor_subject_groups =
|
5
|
+
= link_to 'Not applicable all', Abstractor::UserInterface.abstractor_relative_path(abstractor.update_all_abstractor_abstractions_path(about_type: about.class, about_id: about.id, abstractor_abstraction_value: 'not applicable')), data: { confirm: 'Are you sure?'}, method: :put, class: 'abstractor_not_applicable_all_link'
|
6
|
+
= link_to 'Unknown all', Abstractor::UserInterface.abstractor_relative_path(abstractor.update_all_abstractor_abstractions_path(about_type: about.class, about_id: about.id, abstractor_abstraction_value: 'unknown')), data: { confirm: 'Are you sure?'}, method: :put, class: 'abstractor_unknown_all_link'
|
7
|
+
- abstractor_subject_groups = about.class.abstractor_subject_groups(namespace_type: namespace_type, namespace_id: namespace_id)
|
6
8
|
- abstractor_subject_groups.each do |abstractor_subject_group|
|
7
9
|
.abstractor_subject_groups_container
|
8
10
|
%b= abstractor_subject_group.name
|
@@ -17,13 +19,12 @@
|
|
17
19
|
%b Status
|
18
20
|
%hr
|
19
21
|
.abstractor_subject_groups
|
20
|
-
- abstractor_abstraction_groups =
|
22
|
+
- abstractor_abstraction_groups = about.abstractor_abstraction_groups_by_namespace(namespace_type: namespace_type, namespace_id: namespace_id)
|
21
23
|
- abstractor_abstraction_groups.each_with_index do |abstractor_abstraction_group, index|
|
22
24
|
= render partial: 'abstractor/abstractor_abstraction_groups/form', locals: {abstractor_abstraction_group: abstractor_abstraction_group}
|
23
|
-
= link_to 'Add group', Abstractor::UserInterface.abstractor_relative_path(abstractor.abstractor_abstraction_groups_path(about_id: about.id, about_type: about.class.name, abstractor_subject_group_id: abstractor_subject_group.id)), method: :post, class:
|
24
|
-
|
25
|
+
= link_to 'Add group', Abstractor::UserInterface.abstractor_relative_path(abstractor.abstractor_abstraction_groups_path(about_id: about.id, about_type: about.class.name, abstractor_subject_group_id: abstractor_subject_group.id)), data: { confirm: 'Are you sure?'}, method: :post, class: 'abstractor_group_add_link', remote: true
|
25
26
|
.clear
|
26
|
-
- ungrouped_subjects =
|
27
|
+
- ungrouped_subjects = about.class.abstractor_subjects(grouped: false, namespace_type: namespace_type, namespace_id: namespace_id)
|
27
28
|
- if ungrouped_subjects.any?
|
28
29
|
%fieldset
|
29
30
|
.column-3
|
@@ -39,9 +40,4 @@
|
|
39
40
|
- ungrouped_subject.abstractor_abstractions.not_deleted.where(:about_id => about.id).each do |abstractor_abstraction|
|
40
41
|
%div{ class: "abstractor_abstraction #{Abstractor::Utility.dehumanize(abstractor_abstraction.abstractor_subject.abstractor_abstraction_schema.predicate)}" }
|
41
42
|
= render :partial => 'abstractor/abstractor_abstractions/fields', :locals => {:abstractor_abstraction => abstractor_abstraction}
|
42
|
-
|
43
|
-
$(function () {
|
44
|
-
new Abstractor.AbstractionUI();
|
45
|
-
new Abstractor.AbstractionSuggestionUI();
|
46
|
-
new Abstractor.AbstractionGroupUI();
|
47
|
-
});
|
43
|
+
#abstractor_abstraction_dialog_tooltip
|
@@ -48,14 +48,14 @@
|
|
48
48
|
- abstraction_source.normalize_from_method_to_sources(abstractor_abstraction.about).each do |source|
|
49
49
|
- if source[:source_type] && source[:source_id] && source[:source_method]
|
50
50
|
- dom_id = "#{abstraction_source.id}_#{source[:source_type]}_#{source[:source_id]}_#{source[:source_method]}"
|
51
|
-
%span{ :class => 'abstractor_abstraction_source_tooltip_img
|
51
|
+
%span{ :class => 'abstractor_abstraction_source_tooltip_img', :rel =>"#abstraction_text_#{dom_id}", :title => "#{source[:source_type].to_s} #{source[:source_method]}"}
|
52
52
|
= image_tag('abstractor/page.png', :id => "abstraction_text_link_#{dom_id}")
|
53
53
|
%br
|
54
54
|
%div{ :id => "abstraction_text_#{dom_id}", :class => 'tooltip'}
|
55
55
|
= simple_format(source[:source_type].find(source[:source_id]).send(source[:source_method]))
|
56
56
|
.column-4
|
57
|
-
= f.submit 'Save'
|
58
|
-
= link_to 'Cancel', abstractor_abstraction, :
|
57
|
+
= f.submit 'Save'
|
58
|
+
= link_to 'Cancel', abstractor_abstraction, :remote => true
|
59
59
|
.clear
|
60
60
|
.indirect_sources
|
61
61
|
- abstraction_sources = abstractor_abstraction.abstractor_subject.abstractor_abstraction_sources.select { |s| s.abstractor_abstraction_source_type.name == 'indirect' }
|
@@ -15,8 +15,57 @@ module Abstractor
|
|
15
15
|
end
|
16
16
|
|
17
17
|
module InstanceMethods
|
18
|
-
|
19
|
-
|
18
|
+
##
|
19
|
+
# Returns all abstractions for the abstractable entity by a namespace.
|
20
|
+
#
|
21
|
+
# @param [Hash] options the options to filter the list of abstractions to a namespace.
|
22
|
+
# @option options [String] :namespace_type The type parameter of the namespace.
|
23
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace.
|
24
|
+
# @return [ActiveRecord::Relation] List of [Abstractor::AbstractorAbstraction].
|
25
|
+
def abstractor_abstractions_by_namespace(options = {})
|
26
|
+
options = { namespace_type: nil, namespace_id: nil }.merge(options)
|
27
|
+
if options[:namespace_type] || options[:namespace_id]
|
28
|
+
abstractor_abstractions.not_deleted.where(abstractor_subject_id: self.class.abstractor_subjects(options).map(&:id))
|
29
|
+
else
|
30
|
+
abstractor_abstractions.not_deleted
|
31
|
+
end
|
32
|
+
end
|
33
|
+
##
|
34
|
+
# Returns all abstraction groups for the abstractable entity by a namespace.
|
35
|
+
#
|
36
|
+
# @param [Hash] options the options to filter the list of abstraction groups to a namespace.
|
37
|
+
# @option options [String] :namespace_type The type parameter of the namespace.
|
38
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace.
|
39
|
+
# @return [ActiveRecord::Relation] List of [Abstractor::AbstractorAbstractionGroup].
|
40
|
+
def abstractor_abstraction_groups_by_namespace(options = {})
|
41
|
+
options = { namespace_type: nil, namespace_id: nil }.merge(options)
|
42
|
+
if options[:namespace_type] || options[:namespace_id]
|
43
|
+
abstractor_abstractions_by_namespace(options).map(&:abstractor_abstraction_group).compact.uniq
|
44
|
+
else
|
45
|
+
abstractor_abstraction_groups.not_deleted
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# The method for generating abstractions from the abstractable entity.
|
51
|
+
#
|
52
|
+
# The generation of abstactions is based on the setup of Abstactor::AbstractorAbstactionSchema,
|
53
|
+
# Abstractor::AbstractorSubject, Abstractor::AbstractorSubjectGroup and Abstractor::AbstractorAbstractionSource associated to the abstractable entity.
|
54
|
+
#
|
55
|
+
# Namespacing allows for different sets data points to be associated to the same abstractable entity.
|
56
|
+
#
|
57
|
+
# Namespacing is achieved by setting the Abstractor::AbstractorSubject#namespace_type and Abstractor::AbstractorSubject#namespace_id attributes.
|
58
|
+
#
|
59
|
+
# Passing a namespace to this method will restrict the generation of abstractions to the given namespace. Otherwise, all configured abstractions associated to the abstractable entity will be generated.
|
60
|
+
#
|
61
|
+
# A practical example of the use of a namespace would be two different clincal departments wanting to chart abstract two distinct sets of datapoints for progress notes extracted from an electronic medical record system.
|
62
|
+
# @param [Hash] options the options to filter the generation of abstractions to a namespace.
|
63
|
+
# @option options [String] :namespace_type The type parameter of the namespace.
|
64
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace.
|
65
|
+
# @return [void]
|
66
|
+
def abstract(options = {})
|
67
|
+
options = { namespace_type: nil, namespace_id: nil }.merge(options)
|
68
|
+
self.class.abstractor_subjects(options).each do |abstractor_subject|
|
20
69
|
abstractor_subject.abstract(self)
|
21
70
|
end
|
22
71
|
end
|
@@ -56,24 +105,32 @@ module Abstractor
|
|
56
105
|
# * 'reviewed': Filter abstractions having a determined value (value, unknown or not_applicable).
|
57
106
|
#
|
58
107
|
# @param [String] abstractor_abstraction_status Filter abstractions that need review or are reviews.
|
59
|
-
# @
|
60
|
-
|
108
|
+
# @param [Hash] options the options to filter abstractions to a namespace.
|
109
|
+
# @option options [String] :namespace_type the type parameter of the namespace.
|
110
|
+
# @option options [Integer] :namespace_id the instance parameter of the namespace.
|
111
|
+
# @return [ActiveRecord::Relation] list of [Abstractor::AbstractorAbstraction].
|
112
|
+
def abstractor_abstractions_by_abstractor_abstraction_status(abstractor_abstraction_status, options = {})
|
113
|
+
options = { namespace_type: nil, namespace_id: nil }.merge(options)
|
61
114
|
case abstractor_abstraction_status
|
62
|
-
when
|
63
|
-
|
64
|
-
when
|
65
|
-
|
115
|
+
when Abstractor::Enum::ABSTRACTION_STATUS_NEEDS_REVIEW
|
116
|
+
abstractor_abstractions_by_namespace(options).select { |abstractor_abstraction| abstractor_abstraction.value.blank? && abstractor_abstraction.unknown.blank? && abstractor_abstraction.not_applicable.blank? }
|
117
|
+
when Abstractor::Enum::ABSTRACTION_STATUS_REVIEWED
|
118
|
+
abstractor_abstractions_by_namespace(options).select { |abstractor_abstraction| !abstractor_abstraction.value.blank? || !abstractor_abstraction.unknown.blank? || !abstractor_abstraction.not_applicable.blank? }
|
66
119
|
end
|
67
120
|
end
|
68
121
|
|
69
122
|
##
|
70
|
-
# Removes all abstractions, suggestions and indirect sources for the abstractable entity. Optionally filtred to only '
|
123
|
+
# Removes all abstractions, suggestions and indirect sources for the abstractable entity. Optionally filtred to only 'unreviewed' abstractions and to a given namespace.
|
71
124
|
#
|
72
|
-
# @param [
|
125
|
+
# @param [Hash] options the options to filter the removal of abstractions.
|
126
|
+
# @option options [Booelan] :only_unreviewed Instructs whether to confine removal to only 'unreviewed' abstractions.
|
127
|
+
# @option options [String] :namespace_type The type parameter of the namespace to remove.
|
128
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace to remove.
|
73
129
|
# @return [void]
|
74
|
-
def remove_abstractions(
|
75
|
-
|
76
|
-
|
130
|
+
def remove_abstractions(options = {})
|
131
|
+
options = { only_unreviewed: true, namespace_type: nil, namespace_id: nil }.merge(options)
|
132
|
+
abstractor_abstractions_by_namespace(options).each do |abstractor_abstraction|
|
133
|
+
if !options[:only_unreviewed] || (options[:only_unreviewed] && abstractor_abstraction.unreviewed?)
|
77
134
|
abstractor_abstraction.abstractor_suggestions.each do |abstractor_suggestion|
|
78
135
|
abstractor_suggestion.abstractor_suggestion_sources.destroy_all
|
79
136
|
abstractor_suggestion.abstractor_suggestion_object_value.destroy if abstractor_suggestion.abstractor_suggestion_object_value
|
@@ -96,15 +153,31 @@ module Abstractor
|
|
96
153
|
# * 'reviewed': Filter abstractable entites having no abstractions without a determined value (value, unknown or not_applicable).
|
97
154
|
#
|
98
155
|
# @param [String] abstractor_abstraction_status Filter abstactable entities that an abstraction that 'needs_review' or are all abstractions are 'reviewed'.
|
156
|
+
# @param [Hash] options the options to filter the entities returned.
|
157
|
+
# @option options [String] :namespace_type The type parameter of the namespace to filter the entities.
|
158
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace to filter the entities.
|
99
159
|
# @return [ActiveRecord::Relation] List of abstractable entities.
|
100
|
-
def by_abstractor_abstraction_status(abstractor_abstraction_status)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
160
|
+
def by_abstractor_abstraction_status(abstractor_abstraction_status, options = {})
|
161
|
+
options = { namespace_type: nil, namespace_id: nil }.merge(options)
|
162
|
+
|
163
|
+
if options[:namespace_type] || options[:namespace_id]
|
164
|
+
case abstractor_abstraction_status
|
165
|
+
when Abstractor::Enum::ABSTRACTION_STATUS_NEEDS_REVIEW
|
166
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND 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 = ?))", options[:namespace_type], options[:namespace_id], false, false])
|
167
|
+
when Abstractor::Enum::ABSTRACTION_STATUS_REVIEWED
|
168
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id) AND NOT EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND 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, ?) != ?)", options[:namespace_type], options[:namespace_id], options[:namespace_type], options[:namespace_id], false, true, false, true])
|
169
|
+
else
|
170
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa JOIN abstractor_subjects sub ON aa.abstractor_subject_id = sub.id AND sub.namespace_type = ? AND sub.namespace_id = ? WHERE aa.deleted_at IS NULL AND aa.about_type = '#{self.to_s}' AND #{self.table_name}.id = aa.about_id)", options[:namespace_type], options[:namespace_id]])
|
171
|
+
end
|
106
172
|
else
|
107
|
-
|
173
|
+
case abstractor_abstraction_status
|
174
|
+
when Abstractor::Enum::ABSTRACTION_STATUS_NEEDS_REVIEW
|
175
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.deleted_at IS NULL AND 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])
|
176
|
+
when Abstractor::Enum::ABSTRACTION_STATUS_REVIEWED
|
177
|
+
where(["EXISTS (SELECT 1 FROM abstractor_abstractions aa WHERE aa.deleted_at IS NULL AND 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.deleted_at IS NULL AND 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])
|
178
|
+
else
|
179
|
+
where(nil)
|
180
|
+
end
|
108
181
|
end
|
109
182
|
end
|
110
183
|
|
@@ -113,21 +186,25 @@ module Abstractor
|
|
113
186
|
#
|
114
187
|
# By default, the method will return all abstractor subjects.
|
115
188
|
#
|
116
|
-
# @param [Hash] options the options to filter the
|
189
|
+
# @param [Hash] options the options to filter the subjects returned.
|
117
190
|
# @option options [Boolean] :grouped Filters the list of Abstactor::AbstractorSubject objects to grouped and non-grouped. Defaults to nil which returns all objects.
|
191
|
+
# @option options [String] :namespace_type The type parameter of the namespace to filter the subjects.
|
192
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace to filter the subjects.
|
118
193
|
# @return ActiveRecord::Relation list of Abstactor::AbstractorSubject objects
|
119
194
|
def abstractor_subjects(options = {})
|
120
|
-
options = { grouped: nil }.merge(options)
|
195
|
+
options = { grouped: nil, namespace_type: nil, namespace_id: nil }.merge(options)
|
121
196
|
subjects = Abstractor::AbstractorSubject.where(subject_type: self.to_s)
|
197
|
+
if options[:namespace_type] || options[:namespace_id]
|
198
|
+
subjects = subjects.select { |subject| subject.namespace_type == options[:namespace_type] && subject.namespace_id == options[:namespace_id] }
|
199
|
+
end
|
122
200
|
subjects = case options[:grouped]
|
123
201
|
when true
|
124
|
-
subjects.select{ |s| s.abstractor_subject_group_member}
|
202
|
+
subjects.select{ |s| s.abstractor_subject_group_member }
|
125
203
|
when false
|
126
|
-
subjects.reject{ |s| s.abstractor_subject_group_member}
|
204
|
+
subjects.reject{ |s| s.abstractor_subject_group_member }
|
127
205
|
when nil
|
128
206
|
subjects
|
129
207
|
end
|
130
|
-
subjects
|
131
208
|
end
|
132
209
|
|
133
210
|
##
|
@@ -135,16 +212,19 @@ module Abstractor
|
|
135
212
|
#
|
136
213
|
# By default, the method will return all abstractor abstraction schemas.
|
137
214
|
#
|
138
|
-
# @param [Hash] options the options to filter the
|
139
|
-
# @option options [Boolean] :grouped Filters the list of Abstractor::AbstractorAbstractionSchema objects to grouped and non-grouped. Defaults to nil which returns all
|
215
|
+
# @param [Hash] options the options to filter the abstaction schemas.
|
216
|
+
# @option options [Boolean] :grouped Filters the list of Abstractor::AbstractorAbstractionSchema objects to grouped and non-grouped. Defaults to nil which returns all abstraction schemas.
|
217
|
+
# @option options [String] :namespace_type The type parameter of the namespace to filter the abstaction schemas.
|
218
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace to filter the abstaction schemas.
|
140
219
|
# @return ActiveRecord::Relation list of Abstactor::AbstractorAbstractionSchema objects
|
141
|
-
def abstractor_abstraction_schemas(options= {})
|
142
|
-
options = { grouped: nil }.merge(options)
|
220
|
+
def abstractor_abstraction_schemas(options = {})
|
221
|
+
options = { grouped: nil, namespace_type: nil, namespace_id: nil }.merge(options)
|
143
222
|
abstractor_subjects(options).map(&:abstractor_abstraction_schema)
|
144
223
|
end
|
145
224
|
|
146
|
-
def abstractor_subject_groups
|
147
|
-
|
225
|
+
def abstractor_subject_groups(options = {})
|
226
|
+
options = { grouped: true, namespace_type: nil, namespace_id: nil }.merge(options)
|
227
|
+
abstractor_subjects(options).map(&:abstractor_subject_group).compact.uniq
|
148
228
|
end
|
149
229
|
|
150
230
|
##
|
@@ -159,17 +239,21 @@ module Abstractor
|
|
159
239
|
# it was strucutred like so:
|
160
240
|
# 'select id, collection_date, report_text, has_cancer_diagnosis from pathology_cases'
|
161
241
|
#
|
242
|
+
# @param [Hash] options the options to pivot the abstractions.
|
243
|
+
# @option options [String] :namespace_type The type parameter of the namespace to pivot abstractions.
|
244
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace to pivot abstractions.
|
162
245
|
# @return ActiveRecord::Relation
|
163
|
-
def pivot_abstractions
|
164
|
-
|
246
|
+
def pivot_abstractions(options = {})
|
247
|
+
options = { grouped: false, namespace_type: nil, namespace_id: nil }.merge(options)
|
248
|
+
select = prepare_pivot_select(options)
|
165
249
|
adapter = ActiveRecord::Base.connection.instance_values["config"][:adapter]
|
166
250
|
j = case adapter
|
167
251
|
when 'sqlite3'
|
168
|
-
prepare_pivot_joins(select, "'t'")
|
252
|
+
prepare_pivot_joins(select, "'t'", options)
|
169
253
|
when 'sqlserver'
|
170
|
-
prepare_pivot_joins(select, '1')
|
254
|
+
prepare_pivot_joins(select, '1', options)
|
171
255
|
when 'postgresql'
|
172
|
-
prepare_pivot_joins(select, 'true')
|
256
|
+
prepare_pivot_joins(select, 'true', options)
|
173
257
|
end
|
174
258
|
joins(j).select("#{self.table_name}.*, pivoted_abstractions.*")
|
175
259
|
end
|
@@ -191,18 +275,22 @@ module Abstractor
|
|
191
275
|
# If an abstractable entity has multiple instances of grouped abstractions the entity will be returned mutlple times.
|
192
276
|
#
|
193
277
|
# @param [String] abstractor_subject_groups_name name of {Abstractor::Methods::Models:AbtractorSubjectGroup}
|
278
|
+
# @param [Hash] options the options to pivot the grouped abstractions.
|
279
|
+
# @option options [String] :namespace_type The type parameter of the namespace to pivot grouped abstractions.
|
280
|
+
# @option options [Integer] :namespace_id The instance parameter of the namespace to pivot grouped abstractions.
|
194
281
|
# @return ActiveRecord::Relation
|
195
282
|
# @see Abstractor::Methods::Models:AbstractorSubjectGroup
|
196
|
-
def pivot_grouped_abstractions(abstractor_subject_groups_name)
|
197
|
-
|
283
|
+
def pivot_grouped_abstractions(abstractor_subject_groups_name, options = {})
|
284
|
+
options = { grouped: true, namespace_type: nil, namespace_id: nil }.merge(options)
|
285
|
+
select = prepare_pivot_select(options)
|
198
286
|
adapter = ActiveRecord::Base.connection.instance_values["config"][:adapter]
|
199
287
|
j = case adapter
|
200
288
|
when 'sqlite3'
|
201
|
-
prepare_grouped_pivot_joins(select, "'t'", abstractor_subject_groups_name)
|
289
|
+
prepare_grouped_pivot_joins(select, "'t'", abstractor_subject_groups_name, options)
|
202
290
|
when 'sqlserver'
|
203
|
-
prepare_grouped_pivot_joins(select, '1', abstractor_subject_groups_name)
|
291
|
+
prepare_grouped_pivot_joins(select, '1', abstractor_subject_groups_name, options)
|
204
292
|
when 'postgresql'
|
205
|
-
prepare_grouped_pivot_joins(select, 'true', abstractor_subject_groups_name)
|
293
|
+
prepare_grouped_pivot_joins(select, 'true', abstractor_subject_groups_name, options)
|
206
294
|
end
|
207
295
|
joins(j).select("#{self.table_name}.*, pivoted_abstractions.*")
|
208
296
|
end
|
@@ -219,55 +307,108 @@ module Abstractor
|
|
219
307
|
select = select.join(',')
|
220
308
|
end
|
221
309
|
|
222
|
-
def prepare_pivot_joins(select, bool)
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
310
|
+
def prepare_pivot_joins(select, bool, options = {})
|
311
|
+
if options[:namespace_type] || options[:namespace_id]
|
312
|
+
"LEFT JOIN
|
313
|
+
(
|
314
|
+
SELECT #{self.table_name}.id AS subject_id,
|
315
|
+
#{select}
|
316
|
+
FROM
|
317
|
+
(SELECT aas.predicate
|
318
|
+
, aas.id AS abstractor_abstraction_schema_id
|
319
|
+
, asb.subject_type
|
320
|
+
, aa.about_id
|
321
|
+
, CASE WHEN aa.value IS NOT NULL AND aa.value != '' THEN aa.value WHEN aa.unknown = #{bool} THEN 'unknown' WHEN aa.not_applicable = #{bool} THEN 'not applicable' END AS value
|
322
|
+
FROM abstractor_abstractions aa JOIN abstractor_subjects asb ON aa.abstractor_subject_id = asb.id
|
323
|
+
JOIN abstractor_abstraction_schemas aas ON asb.abstractor_abstraction_schema_id = aas.id
|
324
|
+
WHERE asb.subject_type = '#{self.to_s}'
|
325
|
+
AND asb.namespace_type = '#{options[:namespace_type]}'
|
326
|
+
AND asb.namespace_id = #{options[:namespace_id]}
|
327
|
+
AND NOT EXISTS (
|
328
|
+
SELECT 1
|
329
|
+
FROM abstractor_abstraction_group_members aagm
|
330
|
+
WHERE aa.id = aagm.abstractor_abstraction_id
|
331
|
+
)
|
332
|
+
) data join #{self.table_name} ON data.about_id = #{self.table_name}.id
|
333
|
+
GROUP BY #{self.table_name}.id
|
334
|
+
) pivoted_abstractions ON pivoted_abstractions.subject_id = #{self.table_name}.id
|
335
|
+
"
|
336
|
+
else
|
337
|
+
"LEFT JOIN
|
338
|
+
(
|
339
|
+
SELECT #{self.table_name}.id AS subject_id,
|
340
|
+
#{select}
|
341
|
+
FROM
|
342
|
+
(SELECT aas.predicate
|
343
|
+
, aas.id AS abstractor_abstraction_schema_id
|
344
|
+
, asb.subject_type
|
345
|
+
, aa.about_id
|
346
|
+
, CASE WHEN aa.value IS NOT NULL AND aa.value != '' THEN aa.value WHEN aa.unknown = #{bool} THEN 'unknown' WHEN aa.not_applicable = #{bool} THEN 'not applicable' END AS value
|
347
|
+
FROM abstractor_abstractions aa JOIN abstractor_subjects asb ON aa.abstractor_subject_id = asb.id
|
348
|
+
JOIN abstractor_abstraction_schemas aas ON asb.abstractor_abstraction_schema_id = aas.id
|
349
|
+
WHERE asb.subject_type = '#{self.to_s}'
|
350
|
+
AND NOT EXISTS (
|
351
|
+
SELECT 1
|
352
|
+
FROM abstractor_abstraction_group_members aagm
|
353
|
+
WHERE aa.id = aagm.abstractor_abstraction_id
|
354
|
+
)
|
355
|
+
) data join #{self.table_name} ON data.about_id = #{self.table_name}.id
|
356
|
+
GROUP BY #{self.table_name}.id
|
357
|
+
) pivoted_abstractions ON pivoted_abstractions.subject_id = #{self.table_name}.id
|
358
|
+
"
|
359
|
+
end
|
245
360
|
end
|
246
361
|
|
247
|
-
def prepare_grouped_pivot_joins(select, bool, abstractor_subject_groups_name)
|
248
|
-
abstractor_subject_group = abstractor_subject_groups.detect { |abstractor_subject_group| abstractor_subject_group.name == abstractor_subject_groups_name }
|
362
|
+
def prepare_grouped_pivot_joins(select, bool, abstractor_subject_groups_name, options = {})
|
363
|
+
abstractor_subject_group = abstractor_subject_groups(options).detect { |abstractor_subject_group| abstractor_subject_group.name == abstractor_subject_groups_name }
|
249
364
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
365
|
+
if options[:namespace_type] || options[:namespace_id]
|
366
|
+
"JOIN
|
367
|
+
(
|
368
|
+
SELECT #{self.table_name}.id AS subject_id,
|
369
|
+
#{select}
|
370
|
+
FROM
|
371
|
+
(SELECT aas.predicate
|
372
|
+
, aas.id AS abstraction_schema_id
|
373
|
+
, asb.subject_type
|
374
|
+
, aa.about_id
|
375
|
+
, CASE WHEN aa.value IS NOT NULL AND aa.value != '' THEN aa.value WHEN aa.unknown = #{bool} THEN 'unknown' WHEN aa.not_applicable = #{bool} THEN 'not applicable' END AS value
|
376
|
+
, aag.id AS abstractor_abstraction_group_id
|
377
|
+
FROM abstractor_abstractions aa JOIN abstractor_subjects asb ON aa.abstractor_subject_id = asb.id
|
378
|
+
JOIN abstractor_abstraction_schemas aas ON asb.abstractor_abstraction_schema_id = aas.id
|
379
|
+
JOIN abstractor_abstraction_group_members aagm ON aa.id = aagm.abstractor_abstraction_id
|
380
|
+
JOIN abstractor_abstraction_groups aag ON aagm.abstractor_abstraction_group_id= aag.id
|
381
|
+
WHERE asb.subject_type = '#{self.to_s}'
|
382
|
+
AND asb.namespace_type = '#{options[:namespace_type]}'
|
383
|
+
AND asb.namespace_id = #{options[:namespace_id]}
|
384
|
+
AND aag.abstractor_subject_group_id = #{abstractor_subject_group.id}
|
385
|
+
) data join #{self.table_name} ON data.about_id = #{self.table_name}.id
|
386
|
+
GROUP BY #{self.table_name}.id, abstractor_abstraction_group_id
|
387
|
+
) pivoted_abstractions ON pivoted_abstractions.subject_id = #{self.table_name}.id
|
388
|
+
"
|
389
|
+
else
|
390
|
+
"JOIN
|
391
|
+
(
|
392
|
+
SELECT #{self.table_name}.id AS subject_id,
|
393
|
+
#{select}
|
394
|
+
FROM
|
395
|
+
(SELECT aas.predicate
|
396
|
+
, aas.id AS abstraction_schema_id
|
397
|
+
, asb.subject_type
|
398
|
+
, aa.about_id
|
399
|
+
, CASE WHEN aa.value IS NOT NULL AND aa.value != '' THEN aa.value WHEN aa.unknown = #{bool} THEN 'unknown' WHEN aa.not_applicable = #{bool} THEN 'not applicable' END AS value
|
400
|
+
, aag.id AS abstractor_abstraction_group_id
|
401
|
+
FROM abstractor_abstractions aa JOIN abstractor_subjects asb ON aa.abstractor_subject_id = asb.id
|
402
|
+
JOIN abstractor_abstraction_schemas aas ON asb.abstractor_abstraction_schema_id = aas.id
|
403
|
+
JOIN abstractor_abstraction_group_members aagm ON aa.id = aagm.abstractor_abstraction_id
|
404
|
+
JOIN abstractor_abstraction_groups aag ON aagm.abstractor_abstraction_group_id= aag.id
|
405
|
+
WHERE asb.subject_type = '#{self.to_s}'
|
406
|
+
AND aag.abstractor_subject_group_id = #{abstractor_subject_group.id}
|
407
|
+
) data join #{self.table_name} ON data.about_id = #{self.table_name}.id
|
408
|
+
GROUP BY #{self.table_name}.id, abstractor_abstraction_group_id
|
409
|
+
) pivoted_abstractions ON pivoted_abstractions.subject_id = #{self.table_name}.id
|
410
|
+
"
|
411
|
+
end
|
271
412
|
end
|
272
413
|
end
|
273
414
|
end
|