abstractor 2.1.2 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|