abstractor 4.0.2 → 4.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/javascripts/abstractor/abstractor.js.coffee +13 -4
- data/app/models/abstractor/abstractor_section.rb +5 -0
- data/app/models/abstractor/abstractor_section_name_variant.rb +5 -0
- data/app/models/abstractor/abstractor_section_type.rb +5 -0
- data/app/views/abstractor/abstractor_abstraction_groups/_form.html.haml +7 -2
- data/app/views/abstractor/abstractor_abstraction_groups/edit.html.haml +4 -1
- data/app/views/abstractor/abstractor_abstractions/_fields.html.haml +9 -9
- data/app/views/abstractor/abstractor_abstractions/_grouped_abstractions_list.html.haml +8 -2
- data/app/views/abstractor/abstractor_abstractions/edit.html.haml +3 -2
- data/db/migrate/20141028020332_add_cardinality_to_abstractor_subject_group.rb +5 -0
- data/db/migrate/20141107171413_add_sectioning.rb +41 -0
- data/lib/abstractor/abstractable.rb +24 -5
- data/lib/abstractor/enum.rb +3 -0
- data/lib/abstractor/methods/controllers/abstractor_abstraction_groups_controller.rb +13 -4
- data/lib/abstractor/methods/models/abstractor_abstraction.rb +2 -0
- data/lib/abstractor/methods/models/abstractor_abstraction_group.rb +32 -14
- data/lib/abstractor/methods/models/abstractor_abstraction_group_member.rb +2 -0
- data/lib/abstractor/methods/models/abstractor_abstraction_source.rb +32 -2
- data/lib/abstractor/methods/models/abstractor_section.rb +23 -0
- data/lib/abstractor/methods/models/abstractor_section_name_variant.rb +14 -0
- data/lib/abstractor/methods/models/abstractor_section_type.rb +14 -0
- data/lib/abstractor/methods/models/abstractor_subject.rb +14 -13
- data/lib/abstractor/methods/models/abstractor_subject_group.rb +2 -0
- data/lib/abstractor/methods/models/abstractor_suggestion.rb +3 -2
- data/lib/abstractor/setup.rb +4 -0
- data/lib/abstractor/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzNiYjAyNWRiMDJhYzQwODJkMjJkNDFjMDIzMGRiYzM4NDA1MzZlMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTVlMmQxZjFhM2M3Y2I2NGI5ODQ4ODE5MGVlY2M0MDAxNWZjNWYwOA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MDhkMGRhZjc3ZmNkODk3ZmFhMjYwNTY2OTQxZGVjYWUyMjAyZDczOTA4ZmY0
|
10
|
+
YzAwNDc1YWVjYmNiOGFjNDM5ODU0NmQ0YzBlMDY1YjNlMjg3ZTFmOTM3NTA1
|
11
|
+
YzE2NjEyMGYyYjdjYWJmODRmMjAyZjIxZmVjOTdhNzQ2ZjlkOTI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MDRkN2U5MDg1YTUxNzQzM2EwYmFmNzcxYjc1MTAzMjZkNmViNDdjZDdiNGQ0
|
14
|
+
YmVkYjhkZDE0NjlmNzNmMWJjODhmMzA0NTU5NTFmODA5MzVlMzY2NzhkYTM2
|
15
|
+
OTdkNmU4NjZkNDU3MWRlYTlmOTc4YzdkOWIxNzk1N2QyY2ZjNDc=
|
@@ -84,18 +84,28 @@ Abstractor.AbstractionSuggestionUI = ->
|
|
84
84
|
$(document).on "ajax:success", "form.edit_abstractor_suggestion", (e, data, status, xhr) ->
|
85
85
|
$(this).closest(".abstractor_abstraction").html xhr.responseText
|
86
86
|
return
|
87
|
-
|
88
87
|
return
|
89
88
|
|
90
89
|
Abstractor.AbstractionGroupUI = ->
|
90
|
+
validateCardinality = (group_container) ->
|
91
|
+
group_cardinality = group_container.find('input[name="abstractor_subject_group_cardinality"]')
|
92
|
+
add_group_link = group_container.find('.abstractor_group_add_link')
|
93
|
+
if (group_cardinality.length > 0) && (group_cardinality.val() == group_container.find('.abstractor_abstraction_group_member').length.toString())
|
94
|
+
$(add_group_link).hide()
|
95
|
+
else
|
96
|
+
$(add_group_link).show()
|
97
|
+
|
91
98
|
$(document).on "ajax:success", ".abstractor_abstraction_group .abstractor_group_delete_link", (e, data, status, xhr) ->
|
92
|
-
|
93
|
-
|
99
|
+
subject_groups_container_div = $(this).closest(".abstractor_subject_groups_container")
|
100
|
+
abstraction_group_div = $(this).closest(".abstractor_abstraction_group")
|
101
|
+
abstraction_group_div.html xhr.responseText
|
102
|
+
validateCardinality(subject_groups_container_div)
|
94
103
|
return
|
95
104
|
|
96
105
|
$(document).on "ajax:success", ".abstractor_subject_groups_container .abstractor_group_add_link", (e, data, status, xhr) ->
|
97
106
|
parent_div = $(this).closest(".abstractor_subject_groups_container")
|
98
107
|
parent_div.find(".abstractor_subject_groups").append xhr.responseText
|
108
|
+
validateCardinality(parent_div)
|
99
109
|
return
|
100
110
|
|
101
111
|
$(document).on "ajax:success", ".abstractor_abstraction_group .abstractor_group_not_applicable_all_link", (e, data, status, xhr) ->
|
@@ -107,7 +117,6 @@ Abstractor.AbstractionGroupUI = ->
|
|
107
117
|
parent_div = $(this).closest(".abstractor_abstraction_group")
|
108
118
|
parent_div.html xhr.responseText
|
109
119
|
return
|
110
|
-
|
111
120
|
return
|
112
121
|
|
113
122
|
new Abstractor.AbstractionUI()
|
@@ -1,9 +1,14 @@
|
|
1
|
+
- namespace_type ||= @namespace_type
|
2
|
+
- namespace_id ||= @namespace_id
|
3
|
+
|
1
4
|
- abstractor_abstraction_group ||= @abstractor_abstraction_group
|
2
5
|
|
3
6
|
.abstractor_abstraction_group
|
4
7
|
.abstractor_abstraction_group_member
|
5
|
-
- abstractor_abstractions = abstractor_abstraction_group.abstractor_abstractions.not_deleted.joins(:abstractor_subject => :abstractor_subject_group_member)
|
6
|
-
-
|
8
|
+
- abstractor_abstractions = abstractor_abstraction_group.abstractor_abstractions.not_deleted.joins(:abstractor_subject => :abstractor_subject_group_member)
|
9
|
+
- unless namespace_type.blank? || namespace_id.blank?
|
10
|
+
- abstractor_abstractions = abstractor_abstractions.where(abstractor_subjects: { namespace_type: namespace_type, namespace_id: namespace_id})
|
11
|
+
- abstractor_abstractions.order('abstractor_subject_group_members.display_order').each_with_index do |abstractor_abstraction, index|
|
7
12
|
%div{ class: "abstractor_abstraction #{Abstractor::Utility.dehumanize(abstractor_abstraction.abstractor_subject.abstractor_abstraction_schema.predicate)} #{'abstractor_bottom_border' if index < abstractor_abstractions.length - 1}" }
|
8
13
|
= render :partial => 'abstractor/abstractor_abstractions/fields', :locals => {:abstractor_abstraction => abstractor_abstraction}
|
9
14
|
.abstractor_abstraction_group_actions.abstractor_abstraction_actions
|
@@ -27,18 +27,17 @@
|
|
27
27
|
= abstractor_suggestion.display_value
|
28
28
|
- if abstractor_suggestion.abstractor_suggestion_sources.any?
|
29
29
|
- abstractor_suggestion.abstractor_suggestion_sources.each do |abstractor_suggestion_source|
|
30
|
-
-
|
31
|
-
-
|
32
|
-
- if
|
33
|
-
-
|
34
|
-
|
35
|
-
%span{ class: 'abstractor_abstraction_source_tooltip_img', rel: "#abstraction_text_#{abstractor_suggestion_source.id}", title: "#{source_about.class.to_s} #{from_method}"}
|
30
|
+
- source = { source_type: abstractor_suggestion_source.source_type.constantize, source_id: abstractor_suggestion_source.source_id , source_method: abstractor_suggestion_source.source_method, section_name: abstractor_suggestion_source.section_name }
|
31
|
+
- abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
|
32
|
+
- if abstractor_text
|
33
|
+
- has_text_match = abstractor_text && abstractor_suggestion_source.sentence_match_value
|
34
|
+
%span{ class: 'abstractor_abstraction_source_tooltip_img', rel: "#abstraction_text_#{abstractor_suggestion_source.id}", title: "#{abstractor_suggestion_source.source_type} #{abstractor_suggestion_source.source_method}"}
|
36
35
|
%i{ id: "abstraction_text_link_#{abstractor_suggestion_source.id}", class: "#{'abstraction_text_link_match' if has_text_match}" }
|
37
36
|
%div{ id: "abstraction_text_#{abstractor_suggestion_source.id}", class: 'abstractor_abstraction_source_tooltip'}
|
38
37
|
- if has_text_match
|
39
|
-
= Abstractor::UserInterface.highlight(simple_format(
|
38
|
+
= Abstractor::UserInterface.highlight(simple_format(abstractor_text), abstractor_suggestion_source.sentence_match_value.strip)
|
40
39
|
- else
|
41
|
-
= simple_format(
|
40
|
+
= simple_format(abstractor_text)
|
42
41
|
- if abstractor_suggestion_source.custom_explanation
|
43
42
|
.custom_explanation
|
44
43
|
%label
|
@@ -62,5 +61,6 @@
|
|
62
61
|
%i{ id: "abstraction_text_link_#{dom_id}" }
|
63
62
|
%br
|
64
63
|
%div{ id: "abstraction_text_#{dom_id}", class: 'tooltip'}
|
65
|
-
=
|
64
|
+
- abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
|
65
|
+
= simple_format(abstractor_text)
|
66
66
|
.clear
|
@@ -1,8 +1,13 @@
|
|
1
|
+
- namespace_type ||= @namespace_type
|
2
|
+
- namespace_id ||= @namespace_id
|
3
|
+
|
1
4
|
.abstractor_abstractions_grouped
|
2
5
|
- abstractor_subject_groups = about.class.abstractor_subject_groups(namespace_type: namespace_type, namespace_id: namespace_id)
|
3
6
|
- abstractor_subject_groups.each do |abstractor_subject_group|
|
4
7
|
.abstractor_subject_groups_container
|
5
8
|
%b= abstractor_subject_group.name
|
9
|
+
- if abstractor_subject_group.cardinality
|
10
|
+
= hidden_field_tag :abstractor_subject_group_cardinality, abstractor_subject_group.cardinality, id: "abstractor_subject_group_cardinality_#{abstractor_subject_group.id}"
|
6
11
|
%fieldset
|
7
12
|
.abstractor_abstractions_header
|
8
13
|
.abstractor_abstraction_schema_name
|
@@ -18,6 +23,7 @@
|
|
18
23
|
.abstractor_abstractions_body.abstractor_subject_groups
|
19
24
|
- abstractor_abstraction_groups = about.abstractor_abstraction_groups_by_namespace(namespace_type: namespace_type, namespace_id: namespace_id, abstractor_subject_group_id: abstractor_subject_group.id)
|
20
25
|
- abstractor_abstraction_groups.each do |abstractor_abstraction_group|
|
21
|
-
= render partial: 'abstractor/abstractor_abstraction_groups/form', locals: {abstractor_abstraction_group: abstractor_abstraction_group}
|
22
|
-
|
26
|
+
= render partial: 'abstractor/abstractor_abstraction_groups/form', locals: {abstractor_abstraction_group: abstractor_abstraction_group, namespace_type: namespace_type, namespace_id: namespace_id}
|
27
|
+
- unless abstractor_subject_group.cardinality == 1
|
28
|
+
= 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, namespace_type: namespace_type, namespace_id: namespace_id)), data: { confirm: 'Are you sure?'}, method: :post, class: 'abstractor_group_add_link', remote: true, style: "#{'display: none;' if about.abstractor_subject_group_complete?(abstractor_subject_group.id, {namespace_type: namespace_type, namespace_id: namespace_id})}"
|
23
29
|
.clear
|
@@ -45,13 +45,14 @@
|
|
45
45
|
- abstraction_sources = abstractor_abstraction.abstractor_subject.abstractor_abstraction_sources.select { |s| s.abstractor_abstraction_source_type.name != 'indirect' }
|
46
46
|
- abstraction_sources.each do |abstraction_source|
|
47
47
|
- abstraction_source.normalize_from_method_to_sources(abstractor_abstraction.about).each do |source|
|
48
|
-
-
|
48
|
+
- abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
|
49
|
+
- if abstractor_text
|
49
50
|
- dom_id = "#{abstraction_source.id}_#{source[:source_type]}_#{source[:source_id]}_#{source[:source_method]}"
|
50
51
|
%span{ :class => 'abstractor_abstraction_source_tooltip_img', :rel =>"#abstraction_text_#{dom_id}", :title => "#{source[:source_type].to_s} #{source[:source_method]}"}
|
51
52
|
= image_tag('abstractor/page.png', :id => "abstraction_text_link_#{dom_id}")
|
52
53
|
%br
|
53
54
|
%div{ :id => "abstraction_text_#{dom_id}", :class => 'tooltip'}
|
54
|
-
= simple_format(
|
55
|
+
= simple_format(abstractor_text)
|
55
56
|
.abstraction_edit_abstraction_actions
|
56
57
|
= f.submit 'Save'
|
57
58
|
= link_to 'Cancel', abstractor_abstraction, :remote => true
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class AddSectioning < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
create_table :abstractor_sections do |t|
|
4
|
+
t.integer :abstractor_section_type_id
|
5
|
+
t.string :source_type
|
6
|
+
t.string :source_method
|
7
|
+
t.string :name
|
8
|
+
t.string :description
|
9
|
+
t.string :delimiter
|
10
|
+
t.string :custom_regular_expression
|
11
|
+
t.boolean :return_note_on_empty_section
|
12
|
+
t.datetime :deleted_at
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table :abstractor_section_types do |t|
|
17
|
+
t.string :name
|
18
|
+
t.string :regular_expression
|
19
|
+
t.datetime :deleted_at
|
20
|
+
t.timestamps
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table :abstractor_section_name_variants do |t|
|
24
|
+
t.integer :abstractor_section_id
|
25
|
+
t.string :name
|
26
|
+
t.datetime :deleted_at
|
27
|
+
t.timestamps
|
28
|
+
end
|
29
|
+
|
30
|
+
add_column :abstractor_abstraction_sources, :section_name, :string
|
31
|
+
add_column :abstractor_suggestion_sources, :section_name, :string
|
32
|
+
end
|
33
|
+
|
34
|
+
def down
|
35
|
+
drop_table :abstractor_sections
|
36
|
+
drop_table :abstractor_section_types
|
37
|
+
drop_table :abstractor_section_name_variants
|
38
|
+
remove_column :abstractor_abstraction_sources, :section_name
|
39
|
+
remove_column :abstractor_suggestion_sources, :section_name
|
40
|
+
end
|
41
|
+
end
|
@@ -76,7 +76,7 @@ module Abstractor
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def detect_abstractor_abstraction(abstractor_subject)
|
79
|
-
abstractor_abstractions(true).not_deleted.detect { |abstractor_abstraction| abstractor_abstraction.
|
79
|
+
abstractor_abstractions(true).not_deleted.detect { |abstractor_abstraction| abstractor_abstraction.abstractor_subject_id == abstractor_subject.id }
|
80
80
|
end
|
81
81
|
|
82
82
|
def find_or_create_abstractor_abstraction(abstractor_abstraction_schema, abstractor_subject)
|
@@ -84,25 +84,44 @@ module Abstractor
|
|
84
84
|
else
|
85
85
|
abstractor_abstraction = Abstractor::AbstractorAbstraction.create!(abstractor_subject: abstractor_subject, about: self)
|
86
86
|
if abstractor_subject.groupable?
|
87
|
-
abstractor_abstraction_group =
|
87
|
+
abstractor_abstraction_group = find_or_initialize_abstractor_abstraction_group(abstractor_subject.abstractor_subject_group)
|
88
88
|
abstractor_abstraction_group.abstractor_abstractions << abstractor_abstraction
|
89
|
+
abstractor_abstraction_group.save!
|
89
90
|
end
|
90
91
|
end
|
91
92
|
abstractor_abstraction
|
92
93
|
end
|
93
94
|
|
94
95
|
def detect_abstractor_abstraction_group(abstractor_subject_group)
|
95
|
-
abstractor_abstraction_groups(true).detect { |abstractor_abstraction_group| abstractor_abstraction_group.
|
96
|
+
abstractor_abstraction_groups(true).detect { |abstractor_abstraction_group| abstractor_abstraction_group.abstractor_subject_group_id == abstractor_subject_group.id }
|
96
97
|
end
|
97
98
|
|
98
|
-
def
|
99
|
+
def find_or_initialize_abstractor_abstraction_group(abstractor_subject_group)
|
99
100
|
if abstractor_abstraction_group = detect_abstractor_abstraction_group(abstractor_subject_group)
|
100
101
|
else
|
101
|
-
abstractor_abstraction_group = Abstractor::AbstractorAbstractionGroup.
|
102
|
+
abstractor_abstraction_group = Abstractor::AbstractorAbstractionGroup.new(abstractor_subject_group: abstractor_subject_group, about: self)
|
102
103
|
end
|
103
104
|
abstractor_abstraction_group
|
104
105
|
end
|
105
106
|
|
107
|
+
##
|
108
|
+
# Determines if provided abstractor_subject_group reached number of abstractor_abstraction_groups defined by abstractor_subject_group cardinality
|
109
|
+
#
|
110
|
+
# @param [Integer] abstractor_subject_group_id the id of abstractor_subject_group of interest.
|
111
|
+
# @option options [String] :namespace_type the type parameter of the namespace.
|
112
|
+
# @option options [Integer] :namespace_id the instance parameter of the namespace.
|
113
|
+
# @return [boolean]
|
114
|
+
def abstractor_subject_group_complete?(abstractor_subject_group_id, options = {})
|
115
|
+
abstractor_subject_group = Abstractor::AbstractorSubjectGroup.find(abstractor_subject_group_id)
|
116
|
+
if abstractor_subject_group.cardinality.blank?
|
117
|
+
false
|
118
|
+
else
|
119
|
+
options = { namespace_type: nil, namespace_id: nil, abstractor_subject_group_id: abstractor_subject_group_id }.merge(options)
|
120
|
+
abstractor_abstraction_groups = abstractor_abstraction_groups_by_namespace(options)
|
121
|
+
abstractor_abstraction_groups.length == abstractor_subject_group.cardinality
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
106
125
|
##
|
107
126
|
# Returns all abstraction for the abstractable entity by abstractor_abstraction_status:
|
108
127
|
#
|
data/lib/abstractor/enum.rb
CHANGED
@@ -7,5 +7,8 @@ module Abstractor
|
|
7
7
|
ABSTRACTION_STATUS_NEEDS_REVIEW = 'needs review'
|
8
8
|
ABSTRACTION_STATUS_REVIEWED = 'reviewed'
|
9
9
|
ABSTRACTION_STATUSES = [ABSTRACTION_STATUS_NEEDS_REVIEW, ABSTRACTION_STATUS_REVIEWED]
|
10
|
+
|
11
|
+
ABSTRACTOR_SECTION_TYPE_CUSTOM = 'custom'
|
12
|
+
ABSTRACTOR_SECTION_TYPE_NAME_VALUE = 'name/value'
|
10
13
|
end
|
11
14
|
end
|
@@ -8,16 +8,25 @@ module Abstractor
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def create
|
11
|
-
@abstractor_abstraction_group = Abstractor::AbstractorAbstractionGroup.
|
12
|
-
|
11
|
+
@abstractor_abstraction_group = Abstractor::AbstractorAbstractionGroup.new(abstractor_subject_group_id: params[:abstractor_subject_group_id], about_type: params[:about_type], about_id: params[:about_id])
|
12
|
+
|
13
|
+
abstractor_subjects = @abstractor_abstraction_group.abstractor_subject_group.abstractor_subjects
|
14
|
+
unless params[:namespace_type].blank? || params[:namespace_id].blank?
|
15
|
+
@namespace_id = params[:namespace_id]
|
16
|
+
@namespace_type = params[:namespace_type]
|
17
|
+
abstractor_subjects = abstractor_subjects.where(namespace_type: @namespace_type, namespace_id: @namespace_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
abstractor_subjects.each do |abstractor_subject|
|
13
21
|
abstraction = abstractor_subject.abstractor_abstractions.build(about_id: params[:about_id], about_type: params[:about_type])
|
14
|
-
abstraction.build_abstractor_abstraction_group_member(abstractor_abstraction_group: @abstractor_abstraction_group)
|
15
22
|
abstraction.abstractor_subject.abstractor_abstraction_sources.select { |s| s.abstractor_abstraction_source_type.name == 'indirect' }.each do |abstractor_abstraction_source|
|
16
23
|
source = abstractor_subject.subject_type.constantize.find(params[:about_id]).send(abstractor_abstraction_source.from_method)
|
17
24
|
abstraction.abstractor_indirect_sources.build(abstractor_abstraction_source: abstractor_abstraction_source, source_type: source[:source_type], source_method: source[:source_method])
|
25
|
+
|
18
26
|
end
|
19
|
-
abstraction
|
27
|
+
@abstractor_abstraction_group.abstractor_abstractions << abstraction
|
20
28
|
end
|
29
|
+
@abstractor_abstraction_group.save!
|
21
30
|
|
22
31
|
respond_to do |format|
|
23
32
|
format.html { render action: "edit", layout: false }
|
@@ -22,6 +22,8 @@ module Abstractor
|
|
22
22
|
|
23
23
|
base.send :belongs_to, :about, polymorphic: true
|
24
24
|
|
25
|
+
base.send :validates_associated, :abstractor_subject
|
26
|
+
|
25
27
|
# base.send :attr_accessible, :about, :abstractor_subject, :abstractor_subject_id, :value, :about_type, :about_id, :unknown, :not_applicable, :deleted_at, :abstractor_indirect_sources_attributes
|
26
28
|
|
27
29
|
# Hooks
|
@@ -15,25 +15,43 @@ module Abstractor
|
|
15
15
|
# base.send :attr_accessible, :abstractor_subject_group, :abstractor_subject_group_id, :deleted_at, :about, :about_type, :about_id
|
16
16
|
|
17
17
|
# Hooks
|
18
|
+
base.send :validate, :validate_subject_group_cardinality
|
19
|
+
base.send :validate, :must_have_members
|
20
|
+
|
18
21
|
base.send :after_commit, :update_abstractor_abstraction_group_members, :on => :update, :if => Proc.new { |record| record.previous_changes.include?('deleted_at') }
|
19
|
-
end
|
20
22
|
|
21
|
-
|
22
|
-
# Determines if the group can be removed.
|
23
|
-
#
|
24
|
-
# @return [Boolean]
|
25
|
-
def removable?
|
26
|
-
abstractor_abstractions.map(&:abstractor_suggestions).flatten.empty?
|
23
|
+
base.send(:include, InstanceMethods)
|
27
24
|
end
|
28
25
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
26
|
+
module InstanceMethods
|
27
|
+
##
|
28
|
+
# Determines if the group can be removed.
|
29
|
+
#
|
30
|
+
# @return [Boolean]
|
31
|
+
def removable?
|
32
|
+
abstractor_abstractions.map(&:abstractor_suggestions).flatten.empty?
|
36
33
|
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def update_abstractor_abstraction_group_members
|
37
|
+
return unless deleted?
|
38
|
+
abstractor_abstraction_group_members.each do |gm|
|
39
|
+
gm.soft_delete!
|
40
|
+
gm.abstractor_abstraction.soft_delete!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def must_have_members
|
45
|
+
if self.abstractor_abstraction_group_members.empty? || self.abstractor_abstraction_group_members.all? {|abstractor_abstraction_group_member| abstractor_abstraction_group_member.marked_for_destruction? }
|
46
|
+
errors.add(:base, 'Must have at least one abstractor_abstraction_group_member')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_subject_group_cardinality
|
51
|
+
return if self.abstractor_subject_group.cardinality.blank? || self.persisted?
|
52
|
+
errors.add(:base,"Subject group reached maximum number of abstraction groups (#{abstractor_subject_group.cardinality})") if self.about.abstractor_subject_group_complete?(self.abstractor_subject_group_id)
|
53
|
+
end
|
54
|
+
end
|
37
55
|
end
|
38
56
|
end
|
39
57
|
end
|
@@ -9,6 +9,8 @@ module Abstractor
|
|
9
9
|
base.send :belongs_to, :abstractor_abstraction_group
|
10
10
|
base.send :belongs_to, :abstractor_abstraction
|
11
11
|
|
12
|
+
base.send :validates_associated, :abstractor_abstraction
|
13
|
+
|
12
14
|
# base.send :attr_accessible, :abstractor_abstraction_group, :abstractor_abstraction_group_id, :abstractor_abstraction, :abstractor_abstraction_id, :deleted_at
|
13
15
|
end
|
14
16
|
end
|
@@ -9,11 +9,41 @@ module Abstractor
|
|
9
9
|
base.send :belongs_to, :abstractor_subject
|
10
10
|
base.send :belongs_to, :abstractor_rule_type
|
11
11
|
base.send :belongs_to, :abstractor_abstraction_source_type
|
12
|
+
base.send :belongs_to, :abstractor_abstraction_source_section_type
|
12
13
|
base.send :has_many, :abstractor_suggestion_sources
|
13
14
|
base.send :has_many, :abstractor_abstractions, :through => :abstractor_suggestion_sources
|
14
15
|
base.send :has_many, :abstractor_indirect_sources
|
16
|
+
base.send :has_many, :abstractor_abstraction_source_section_name_variants
|
15
17
|
|
16
|
-
|
18
|
+
def base.abstractor_text(source)
|
19
|
+
text = source[:source_type].find(source[:source_id]).send(source[:source_method])
|
20
|
+
if !source[:section_name].blank?
|
21
|
+
abstractor_section = Abstractor::AbstractorSection.where(source_type: source[:source_type], source_method: source[:source_method], name: source[:section_name]).first
|
22
|
+
if text =~ prepare_section_regular_expression(abstractor_section)
|
23
|
+
text = $2
|
24
|
+
else
|
25
|
+
if abstractor_section.return_note_on_empty_section
|
26
|
+
text = text
|
27
|
+
else
|
28
|
+
text = ''
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
text
|
34
|
+
end
|
35
|
+
|
36
|
+
def base.prepare_section_regular_expression(abstractor_section)
|
37
|
+
regular_expression = nil
|
38
|
+
if abstractor_section.abstractor_section_type.name == Abstractor::Enum::ABSTRACTOR_SECTION_TYPE_CUSTOM
|
39
|
+
regular_expression = abstractor_section.custom_regular_expression
|
40
|
+
else
|
41
|
+
regular_expression = abstractor_section.abstractor_section_type.regular_expression
|
42
|
+
end
|
43
|
+
regular_expression.gsub!('section_name_variants', abstractor_section.prepare_section_name_variants)
|
44
|
+
regular_expression.gsub!('delimiter', abstractor_section.delimiter)
|
45
|
+
Regexp.new(regular_expression, Regexp::IGNORECASE)
|
46
|
+
end
|
17
47
|
end
|
18
48
|
|
19
49
|
def normalize_from_method_to_sources(about)
|
@@ -21,7 +51,7 @@ module Abstractor
|
|
21
51
|
fm = nil
|
22
52
|
fm = about.send(from_method) unless from_method.blank?
|
23
53
|
if fm.is_a?(String) || fm.nil?
|
24
|
-
sources = [{ source_type: about.class , source_id: about.id , source_method: from_method }]
|
54
|
+
sources = [{ source_type: about.class , source_id: about.id , source_method: from_method, section_name: section_name }]
|
25
55
|
else
|
26
56
|
sources = fm
|
27
57
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Abstractor
|
2
|
+
module Methods
|
3
|
+
module Models
|
4
|
+
module AbstractorSection
|
5
|
+
def self.included(base)
|
6
|
+
base.send :include, SoftDelete
|
7
|
+
|
8
|
+
# Associations
|
9
|
+
base.send :belongs_to, :abstractor_section_type
|
10
|
+
base.send :has_many, :abstractor_section_name_variants
|
11
|
+
end
|
12
|
+
|
13
|
+
def prepare_section_name_variants
|
14
|
+
section_name_variants.join('|')
|
15
|
+
end
|
16
|
+
|
17
|
+
def section_name_variants
|
18
|
+
[name].concat(abstractor_section_name_variants.map(&:name))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -129,7 +129,7 @@ module Abstractor
|
|
129
129
|
def abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
|
130
130
|
suggestions = about.send(abstractor_abstraction_source.custom_method)
|
131
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])
|
132
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, about.id, about.class.to_s, abstractor_abstraction_source.from_method, abstractor_abstraction_source.section_name, suggestion[:suggestion], nil, nil, abstractor_abstraction_source.custom_method, suggestion[:explanation])
|
133
133
|
end
|
134
134
|
create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source)
|
135
135
|
end
|
@@ -145,7 +145,7 @@ module Abstractor
|
|
145
145
|
|
146
146
|
def abstract_sentential_value(about, abstractor_abstraction, abstractor_abstraction_source)
|
147
147
|
abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
|
148
|
-
abstractor_text =
|
148
|
+
abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
|
149
149
|
abstractor_object_value_ids = abstractor_abstraction_schema.abstractor_object_values.map(&:id)
|
150
150
|
|
151
151
|
abstractor_object_values = []
|
@@ -187,7 +187,7 @@ module Abstractor
|
|
187
187
|
Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], object_variant)
|
188
188
|
)
|
189
189
|
if !reject
|
190
|
-
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)
|
190
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, object_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], abstractor_object_value, nil, nil, nil, nil)
|
191
191
|
end
|
192
192
|
end
|
193
193
|
end
|
@@ -206,7 +206,7 @@ module Abstractor
|
|
206
206
|
|
207
207
|
def abstract_canonical_name_value(about, abstractor_abstraction, abstractor_abstraction_source)
|
208
208
|
abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
|
209
|
-
abstractor_text =
|
209
|
+
abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
|
210
210
|
parser = Abstractor::Parser.new(abstractor_text)
|
211
211
|
abstractor_abstraction_schema.predicate_variants.each do |predicate_variant|
|
212
212
|
abstractor_abstraction_schema.abstractor_object_values.each do |abstractor_object_value|
|
@@ -214,13 +214,13 @@ module Abstractor
|
|
214
214
|
match_value = "#{Regexp.escape(predicate_variant)}:\s*#{Regexp.escape(object_variant)}"
|
215
215
|
matches = parser.scan(match_value, word_boundary: true).uniq
|
216
216
|
matches.each do |match|
|
217
|
-
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)
|
217
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], abstractor_object_value, nil, nil, nil, nil)
|
218
218
|
end
|
219
219
|
|
220
220
|
match_value = "#{Regexp.escape(predicate_variant)}#{Regexp.escape(object_variant)}"
|
221
221
|
matches = parser.scan(match_value, word_boundary: true).uniq
|
222
222
|
matches.each do |match|
|
223
|
-
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)
|
223
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], source[:seciton_name], abstractor_object_value, nil, nil, nil, nil)
|
224
224
|
end
|
225
225
|
end
|
226
226
|
end
|
@@ -230,7 +230,7 @@ module Abstractor
|
|
230
230
|
|
231
231
|
def abstract_sentential_name_value(about, abstractor_abstraction, abstractor_abstraction_source)
|
232
232
|
abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
|
233
|
-
abstractor_text =
|
233
|
+
abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
|
234
234
|
parser = Abstractor::Parser.new(abstractor_text)
|
235
235
|
abstractor_abstraction_schema.predicate_variants.each do |predicate_variant|
|
236
236
|
ranges = parser.range_all(Regexp.escape(predicate_variant))
|
@@ -250,7 +250,7 @@ module Abstractor
|
|
250
250
|
Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], object_variant)
|
251
251
|
)
|
252
252
|
if !reject
|
253
|
-
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)
|
253
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, sentence[:sentence], sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], abstractor_object_value, nil, nil, nil, nil)
|
254
254
|
end
|
255
255
|
end
|
256
256
|
end
|
@@ -262,7 +262,7 @@ module Abstractor
|
|
262
262
|
end
|
263
263
|
end
|
264
264
|
|
265
|
-
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)
|
265
|
+
def suggest(abstractor_abstraction, abstractor_abstraction_source, match_value, sentence_match_value, source_id, source_type, source_method, section_name, suggested_value, unknown, not_applicable, custom_method, custom_explanation)
|
266
266
|
match_value.strip! unless match_value.nil?
|
267
267
|
sentence_match_value.strip! unless sentence_match_value.nil?
|
268
268
|
if abstractor_object_value?(suggested_value)
|
@@ -283,7 +283,7 @@ module Abstractor
|
|
283
283
|
abstractor_suggestion.abstractor_suggestion_object_value = Abstractor::AbstractorSuggestionObjectValue.new(abstractor_object_value: abstractor_object_value) if abstractor_object_value
|
284
284
|
end
|
285
285
|
|
286
|
-
abstractor_suggestion_source = abstractor_suggestion.detect_abstractor_suggestion_source(abstractor_abstraction_source, sentence_match_value, source_id, source_type, source_method)
|
286
|
+
abstractor_suggestion_source = abstractor_suggestion.detect_abstractor_suggestion_source(abstractor_abstraction_source, sentence_match_value, source_id, source_type, source_method, section_name)
|
287
287
|
if !abstractor_suggestion_source
|
288
288
|
Abstractor::AbstractorSuggestionSource.create(
|
289
289
|
abstractor_abstraction_source: abstractor_abstraction_source,
|
@@ -293,6 +293,7 @@ module Abstractor
|
|
293
293
|
source_id: source_id,
|
294
294
|
source_type: source_type,
|
295
295
|
source_method: source_method,
|
296
|
+
section_name: section_name,
|
296
297
|
custom_method: custom_method,
|
297
298
|
custom_explanation: custom_explanation
|
298
299
|
)
|
@@ -306,7 +307,7 @@ module Abstractor
|
|
306
307
|
|
307
308
|
def create_unknown_abstractor_suggestion_name_only(about, abstractor_abstraction, abstractor_abstraction_source)
|
308
309
|
abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
|
309
|
-
abstractor_text =
|
310
|
+
abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source)
|
310
311
|
parser = Abstractor::Parser.new(abstractor_text)
|
311
312
|
#Create an 'unknown' suggestion based on match name only if we have not made a suggstion
|
312
313
|
if abstractor_abstraction.abstractor_suggestions(true).empty?
|
@@ -322,7 +323,7 @@ module Abstractor
|
|
322
323
|
Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], predicate_variant)
|
323
324
|
)
|
324
325
|
if !reject
|
325
|
-
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)
|
326
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, predicate_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], nil, true, nil, nil, nil)
|
326
327
|
end
|
327
328
|
end
|
328
329
|
end
|
@@ -336,7 +337,7 @@ module Abstractor
|
|
336
337
|
#Create an 'unknown' suggestion based on matching nothing only if we have not made a suggstion
|
337
338
|
abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source|
|
338
339
|
if abstractor_abstraction.abstractor_suggestions(true).select { |abstractor_suggestion| abstractor_suggestion.unknown != true }.empty?
|
339
|
-
suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, source[:source_id], source[:source_type].to_s, source[:source_method],
|
340
|
+
suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, source[:source_id], source[:source_type].to_s, source[:source_method],source[:section_name], nil, true, nil, nil, nil)
|
340
341
|
end
|
341
342
|
end
|
342
343
|
end
|
@@ -12,6 +12,8 @@ module Abstractor
|
|
12
12
|
base.send :has_many, :abstractor_abstractions, :through => :abstractor_abstraction_groups
|
13
13
|
|
14
14
|
# base.send :attr_accessible, :deleted_at, :name
|
15
|
+
# Validations
|
16
|
+
base.send :validates, :cardinality, numericality: { only_integer: true, greater_than: 0 }, unless: Proc.new { |a| a.cardinality.blank? }
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -74,13 +74,14 @@ module Abstractor
|
|
74
74
|
abstractor_abstraction.abstractor_suggestions.where('id != ?', id)
|
75
75
|
end
|
76
76
|
|
77
|
-
def detect_abstractor_suggestion_source(abstractor_abstraction_source, sentence_match_value, source_id, source_type, source_method)
|
77
|
+
def detect_abstractor_suggestion_source(abstractor_abstraction_source, sentence_match_value, source_id, source_type, source_method, section_name)
|
78
78
|
abstractor_suggestion_source = abstractor_suggestion_sources.detect do |abstractor_suggestion_source|
|
79
79
|
abstractor_suggestion_source.abstractor_abstraction_source == abstractor_abstraction_source &&
|
80
80
|
abstractor_suggestion_source.sentence_match_value == sentence_match_value &&
|
81
81
|
abstractor_suggestion_source.source_id == source_id &&
|
82
82
|
abstractor_suggestion_source.source_type == source_type &&
|
83
|
-
abstractor_suggestion_source.source_method == source_method
|
83
|
+
abstractor_suggestion_source.source_method == source_method &&
|
84
|
+
abstractor_suggestion_source.section_name == section_name
|
84
85
|
end
|
85
86
|
end
|
86
87
|
end
|
data/lib/abstractor/setup.rb
CHANGED
@@ -28,6 +28,10 @@ module Abstractor
|
|
28
28
|
Abstractor::AbstractorAbstractionSourceType.where(name: 'nlp suggestion').first_or_create
|
29
29
|
Abstractor::AbstractorAbstractionSourceType.where(name: 'custom suggestion').first_or_create
|
30
30
|
Abstractor::AbstractorAbstractionSourceType.where(name: 'indirect').first_or_create
|
31
|
+
|
32
|
+
puts 'Setting up Abstractor::AbstractorSectionType'
|
33
|
+
Abstractor::AbstractorSectionType.where(name: Abstractor::Enum::ABSTRACTOR_SECTION_TYPE_CUSTOM).first_or_create
|
34
|
+
Abstractor::AbstractorSectionType.where(name: Abstractor::Enum::ABSTRACTOR_SECTION_TYPE_NAME_VALUE, regular_expression: "(?<=^|[\r\n])(section_name_variants)[\s]*delimiter([^\r\n]*(?:[\r\n]+(?![A-Z].*delimiter).*)*)").first_or_create
|
31
35
|
end
|
32
36
|
end
|
33
37
|
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: 4.0
|
4
|
+
version: 4.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-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -465,6 +465,9 @@ files:
|
|
465
465
|
- app/models/abstractor/abstractor_object_value_variant.rb
|
466
466
|
- app/models/abstractor/abstractor_relation_type.rb
|
467
467
|
- app/models/abstractor/abstractor_rule_type.rb
|
468
|
+
- app/models/abstractor/abstractor_section.rb
|
469
|
+
- app/models/abstractor/abstractor_section_name_variant.rb
|
470
|
+
- app/models/abstractor/abstractor_section_type.rb
|
468
471
|
- app/models/abstractor/abstractor_subject.rb
|
469
472
|
- app/models/abstractor/abstractor_subject_group.rb
|
470
473
|
- app/models/abstractor/abstractor_subject_group_member.rb
|
@@ -512,6 +515,8 @@ files:
|
|
512
515
|
- db/migrate/20140718014952_refactor_abstractor_rule_types.rb
|
513
516
|
- db/migrate/20140803205149_add_custom_explanation_to_abstractor_suggestion_sources.rb
|
514
517
|
- db/migrate/20140816005228_add_namespace_to_abstractor_subjects.rb
|
518
|
+
- db/migrate/20141028020332_add_cardinality_to_abstractor_subject_group.rb
|
519
|
+
- db/migrate/20141107171413_add_sectioning.rb
|
515
520
|
- db/seeds.rb
|
516
521
|
- lib/abstractor.rb
|
517
522
|
- lib/abstractor/abstractable.rb
|
@@ -536,6 +541,9 @@ files:
|
|
536
541
|
- lib/abstractor/methods/models/abstractor_object_value_variant.rb
|
537
542
|
- lib/abstractor/methods/models/abstractor_relation_type.rb
|
538
543
|
- lib/abstractor/methods/models/abstractor_rule_type.rb
|
544
|
+
- lib/abstractor/methods/models/abstractor_section.rb
|
545
|
+
- lib/abstractor/methods/models/abstractor_section_name_variant.rb
|
546
|
+
- lib/abstractor/methods/models/abstractor_section_type.rb
|
539
547
|
- lib/abstractor/methods/models/abstractor_subject.rb
|
540
548
|
- lib/abstractor/methods/models/abstractor_subject_group.rb
|
541
549
|
- lib/abstractor/methods/models/abstractor_subject_group_member.rb
|