discerner 1.1.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +97 -0
- data/Rakefile +29 -0
- data/app/assets/images/discerner/add.png +0 -0
- data/app/assets/images/discerner/ajax-loader.gif +0 -0
- data/app/assets/images/discerner/bar.gif +0 -0
- data/app/assets/images/discerner/bullet_arrow_down.png +0 -0
- data/app/assets/images/discerner/bullet_arrow_up.png +0 -0
- data/app/assets/images/discerner/cog.png +0 -0
- data/app/assets/images/discerner/delete.png +0 -0
- data/app/assets/images/discerner/edit.png +0 -0
- data/app/assets/images/discerner/excel.png +0 -0
- data/app/assets/images/discerner/greencheck.gif +0 -0
- data/app/assets/images/discerner/rails.png +0 -0
- data/app/assets/images/discerner/show.png +0 -0
- data/app/assets/images/discerner/switch_minus.gif +0 -0
- data/app/assets/images/discerner/switch_plus.gif +0 -0
- data/app/assets/javascripts/discerner/application.js +20 -0
- data/app/assets/javascripts/discerner/combobox.js +301 -0
- data/app/assets/javascripts/discerner/discerner.js +19 -0
- data/app/assets/javascripts/discerner/export_parameters.js +13 -0
- data/app/assets/javascripts/discerner/jquery/jquery.blockUI.js +576 -0
- data/app/assets/javascripts/discerner/jquery/jquery.form.js +1074 -0
- data/app/assets/javascripts/discerner/nested_attributes.js +69 -0
- data/app/assets/javascripts/discerner/search_combinations.js +49 -0
- data/app/assets/javascripts/discerner/search_parameter.js +131 -0
- data/app/assets/javascripts/discerner/search_parameter_value.js +172 -0
- data/app/assets/javascripts/discerner/searches.js +93 -0
- data/app/assets/javascripts/discerner/url.js +42 -0
- data/app/assets/stylesheets/discerner/application.css +16 -0
- data/app/assets/stylesheets/discerner/buttons.sass +13 -0
- data/app/assets/stylesheets/discerner/categorized_autocompleter.sass +53 -0
- data/app/assets/stylesheets/discerner/discerner.sass +51 -0
- data/app/assets/stylesheets/discerner/export_parameters.sass +43 -0
- data/app/assets/stylesheets/discerner/links.sass +29 -0
- data/app/assets/stylesheets/discerner/searches.sass +205 -0
- data/app/assets/stylesheets/discerner/tables.sass +32 -0
- data/app/controllers/discerner/application_controller.rb +2 -0
- data/app/controllers/discerner/export_parameters_controller.rb +5 -0
- data/app/controllers/discerner/parameters_controller.rb +5 -0
- data/app/controllers/discerner/searches_controller.rb +5 -0
- data/app/helpers/discerner/application_helper.rb +4 -0
- data/app/helpers/discerner/parameters_helper.rb +5 -0
- data/app/helpers/discerner/searches_helper.rb +5 -0
- data/app/models/discerner/dictionary.rb +5 -0
- data/app/models/discerner/export_parameter.rb +5 -0
- data/app/models/discerner/operator.rb +5 -0
- data/app/models/discerner/parameter.rb +5 -0
- data/app/models/discerner/parameter_category.rb +5 -0
- data/app/models/discerner/parameter_type.rb +5 -0
- data/app/models/discerner/parameter_value.rb +5 -0
- data/app/models/discerner/parameter_value_categorization.rb +5 -0
- data/app/models/discerner/parameter_value_category.rb +5 -0
- data/app/models/discerner/search.rb +5 -0
- data/app/models/discerner/search_combination.rb +5 -0
- data/app/models/discerner/search_parameter.rb +5 -0
- data/app/models/discerner/search_parameter_value.rb +5 -0
- data/app/views/discerner/export_parameters/index.html.haml +55 -0
- data/app/views/discerner/parameters/_values_autocompleter.html.haml +49 -0
- data/app/views/discerner/parameters/values.html.haml +1 -0
- data/app/views/discerner/searches/_form.html.haml +21 -0
- data/app/views/discerner/searches/_form_combined_searches.html.haml +32 -0
- data/app/views/discerner/searches/_form_controls.html.haml +8 -0
- data/app/views/discerner/searches/_form_header.html.haml +39 -0
- data/app/views/discerner/searches/_form_search_parameters.html.haml +28 -0
- data/app/views/discerner/searches/_list.html.haml +17 -0
- data/app/views/discerner/searches/_search_combination_fields.html.haml +22 -0
- data/app/views/discerner/searches/_search_parameter_fields.html.haml +48 -0
- data/app/views/discerner/searches/_search_parameter_value_fields.html.haml +62 -0
- data/app/views/discerner/searches/_summary.html.haml +25 -0
- data/app/views/discerner/searches/edit.html.haml +8 -0
- data/app/views/discerner/searches/index.html.haml +13 -0
- data/app/views/discerner/searches/index.js.haml +1 -0
- data/app/views/discerner/searches/new.html.haml +3 -0
- data/app/views/discerner/searches/rename.html.haml +6 -0
- data/app/views/discerner/searches/update.js.haml +7 -0
- data/app/views/discerner/shared/_categorized_autocompleter_items.html.haml +15 -0
- data/app/views/discerner/shared/_error_messages.html.haml +5 -0
- data/app/views/layouts/discerner/searches.html.erb +17 -0
- data/config/cucumber.yml +8 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20121004040716_create_discerner_dictionaries.rb +11 -0
- data/db/migrate/20121004153043_create_discerner_parameter_categories.rb +12 -0
- data/db/migrate/20121005194843_create_discerner_parameter_types.rb +11 -0
- data/db/migrate/20121005203223_create_discerner_parameters.rb +14 -0
- data/db/migrate/20121008154855_create_discerner_operators.rb +13 -0
- data/db/migrate/20121008160313_create_discerner_operators_parameter_types.rb +8 -0
- data/db/migrate/20121008161455_create_discerner_parameter_values.rb +13 -0
- data/db/migrate/20121008180829_create_discerner_searches.rb +11 -0
- data/db/migrate/20121008182443_create_discerner_search_parameters.rb +11 -0
- data/db/migrate/20121011205130_create_discerner_search_parameter_values.rb +15 -0
- data/db/migrate/20121211213215_add_dictionary_id_to_discerner_searches.rb +5 -0
- data/db/migrate/20130205193602_create_discerner_search_combinations.rb +12 -0
- data/db/migrate/20130211230636_create_discerner_export_parameters.rb +9 -0
- data/db/migrate/20130213185818_add_search_columns_to_discerner_parameters.rb +38 -0
- data/db/migrate/20130213205255_rename_database_name_to_search_value_in_discerner_parameter_values.rb +5 -0
- data/db/migrate/20130215165416_add_searchable_to_discerner_parameters.rb +5 -0
- data/db/migrate/20130218230257_add_exclusive_to_discerner_parameters.rb +5 -0
- data/db/migrate/20130220163015_replace_integer_type_with_numeric.rb +22 -0
- data/db/migrate/20130221172826_add_unique_identifier_to_discerner_parameters.rb +5 -0
- data/db/migrate/20130222052924_change_search_attribute_to_method.rb +29 -0
- data/db/migrate/20130222070959_add_export_columns_to_discerner_parameters.rb +6 -0
- data/db/migrate/20130227031747_add_unique_identifier_to_discerner_operators.rb +16 -0
- data/db/migrate/20130306015019_change_discerner_parameter_values_name.rb +9 -0
- data/db/migrate/20130306212430_add_deleted_at_to_discerner_search_parameters.rb +5 -0
- data/db/migrate/20130306212504_add_deleted_at_to_discerner_search_parameter_values.rb +5 -0
- data/db/migrate/20130306212527_add_deleted_at_to_discerner_search_combinations.rb +5 -0
- data/db/migrate/20130306212818_add_deleted_at_to_discerner_export_parameters.rb +5 -0
- data/db/migrate/20130311190717_add_operator_type_to_discerner_operators.rb +5 -0
- data/db/migrate/20131212175110_remove_extra_search_parameter_values.rb +10 -0
- data/db/migrate/20140204170625_create_discerner_parameter_value_categories.rb +16 -0
- data/db/migrate/20140204170646_create_discerner_parameter_value_categorizations.rb +12 -0
- data/db/migrate/20140227191827_remove_blank_parameter_values_from_export_parameters.rb +10 -0
- data/db/seeds.rb +0 -0
- data/lib/discerner/engine.rb +16 -0
- data/lib/discerner/methods/controllers/export_parameters_controller.rb +38 -0
- data/lib/discerner/methods/controllers/parameters_controller.rb +30 -0
- data/lib/discerner/methods/controllers/searches_controller.rb +204 -0
- data/lib/discerner/methods/helpers/searches_helper.rb +145 -0
- data/lib/discerner/methods/models/dictionary.rb +54 -0
- data/lib/discerner/methods/models/export_parameter.rb +35 -0
- data/lib/discerner/methods/models/operator.rb +42 -0
- data/lib/discerner/methods/models/parameter.rb +90 -0
- data/lib/discerner/methods/models/parameter_category.rb +60 -0
- data/lib/discerner/methods/models/parameter_type.rb +33 -0
- data/lib/discerner/methods/models/parameter_value.rb +87 -0
- data/lib/discerner/methods/models/parameter_value_categorization.rb +21 -0
- data/lib/discerner/methods/models/parameter_value_category.rb +45 -0
- data/lib/discerner/methods/models/search.rb +147 -0
- data/lib/discerner/methods/models/search_combination.rb +50 -0
- data/lib/discerner/methods/models/search_parameter.rb +128 -0
- data/lib/discerner/methods/models/search_parameter_value.rb +130 -0
- data/lib/discerner/methods/models/soft_delete.rb +35 -0
- data/lib/discerner/methods/models/warning.rb +15 -0
- data/lib/discerner/parser.rb +497 -0
- data/lib/discerner/version.rb +3 -0
- data/lib/discerner.rb +4 -0
- data/lib/generators/discerner/dictionary/dictionary_generator.rb +38 -0
- data/lib/generators/discerner/dictionary/templates/model.rb +15 -0
- data/lib/generators/discerner/dictionary/templates/show.xls.erb +37 -0
- data/lib/generators/discerner/dictionary/templates/view.html.haml +2 -0
- data/lib/generators/discerner/install/install_generator.rb +153 -0
- data/lib/generators/discerner/install/templates/controllers/export_parameters_controller.rb +20 -0
- data/lib/generators/discerner/install/templates/controllers/parameters_controller.rb +15 -0
- data/lib/generators/discerner/install/templates/controllers/searches_controller.rb +39 -0
- data/lib/generators/discerner/install/templates/dictionaries.yml +236 -0
- data/lib/generators/discerner/install/templates/helpers/searches_helper.rb +9 -0
- data/lib/generators/discerner/install/templates/models/book.rb +15 -0
- data/lib/generators/discerner/install/templates/models/dictionary.rb +9 -0
- data/lib/generators/discerner/install/templates/models/export_parameter.rb +9 -0
- data/lib/generators/discerner/install/templates/models/operator.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter.rb +10 -0
- data/lib/generators/discerner/install/templates/models/parameter_category.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter_type.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter_value.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter_value_categorization.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter_value_category.rb +9 -0
- data/lib/generators/discerner/install/templates/models/search.rb +9 -0
- data/lib/generators/discerner/install/templates/models/search_combination.rb +9 -0
- data/lib/generators/discerner/install/templates/models/search_parameter.rb +9 -0
- data/lib/generators/discerner/install/templates/models/search_parameter_value.rb +9 -0
- data/lib/generators/discerner/install/templates/views/layouts/searches.html.erb +17 -0
- data/lib/setup/operators.yml +91 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/lib/tasks/discerner_tasks.rake +30 -0
- metadata +531 -0
@@ -0,0 +1,128 @@
|
|
1
|
+
module Discerner
|
2
|
+
module Methods
|
3
|
+
module Models
|
4
|
+
module SearchParameter
|
5
|
+
def self.included(base)
|
6
|
+
base.send :include, SoftDelete
|
7
|
+
base.send :include, Warning
|
8
|
+
|
9
|
+
# Associations
|
10
|
+
base.send :belongs_to, :search, :inverse_of => :search_parameters
|
11
|
+
base.send :belongs_to, :parameter, :inverse_of => :search_parameters
|
12
|
+
base.send :has_many, :search_parameter_values, :dependent => :destroy, :inverse_of => :search_parameter
|
13
|
+
|
14
|
+
# Scopes
|
15
|
+
base.send(:scope, :by_parameter_category, ->(parameter_category) { base.includes(:parameter).where('discerner_parameters.parameter_category_id' => parameter_category.id) unless parameter_category.blank?})
|
16
|
+
base.send(:scope, :ordered_by_display_order, -> { base.order('discerner_search_parameters.display_order ASC') })
|
17
|
+
base.send(:scope, :ordered, -> { base.order('discerner_search_parameters.id ASC') })
|
18
|
+
|
19
|
+
#Validations
|
20
|
+
base.send :validates_presence_of, :search, :parameter
|
21
|
+
|
22
|
+
# Nested attributes
|
23
|
+
base.send :accepts_nested_attributes_for, :search_parameter_values, :allow_destroy => true
|
24
|
+
|
25
|
+
# Hooks
|
26
|
+
base.send :after_commit, :update_associations, :on => :update, :if => Proc.new { |record| record.previous_changes.include?('deleted_at') }
|
27
|
+
|
28
|
+
# Whitelisting attributes
|
29
|
+
base.send :attr_accessible, :search, :search_id, :parameter, :parameter_id, :search_parameter_values_attributes, :display_order
|
30
|
+
end
|
31
|
+
|
32
|
+
# Instance Methods
|
33
|
+
def initialize(*args)
|
34
|
+
super(*args)
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_search_parameters
|
38
|
+
if self.search_parameters.size < 1 || self.search_parameters.all?{|search_parameter| search_parameter.marked_for_destruction? }
|
39
|
+
errors.add(:base,"Search should have at least one search criteria.")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def parameterized_name
|
44
|
+
name.blank? ? 'no_name_specified' : name.parameterize.underscore
|
45
|
+
end
|
46
|
+
|
47
|
+
def prepare_sql
|
48
|
+
sql = {}
|
49
|
+
parameter_type = parameter.parameter_type.name
|
50
|
+
case parameter_type
|
51
|
+
when 'list'
|
52
|
+
values = [search_parameter_values.chosen.map { |spv| spv.parameter_value.search_value }]
|
53
|
+
predicate = "#{parameter.search_method} in (?)"
|
54
|
+
when 'combobox'
|
55
|
+
values = [search_parameter_values.map { |spv| spv.parameter_value.search_value unless spv.parameter_value.nil? }.compact]
|
56
|
+
predicate = "#{parameter.search_method} in (?)" unless values.blank?
|
57
|
+
else # 'numeric','date', 'text', 'string
|
58
|
+
spvs = []
|
59
|
+
values = []
|
60
|
+
search_parameter_values.map {|spv| spvs << spv.to_sql}
|
61
|
+
|
62
|
+
predicates = spvs.map { |s| s[:predicates] }.join(' or ')
|
63
|
+
predicate = "(#{predicates})"
|
64
|
+
|
65
|
+
spvs.each do |spv|
|
66
|
+
if spv[:values].is_a?(Array)
|
67
|
+
spv[:values].each do |v|
|
68
|
+
values << v
|
69
|
+
end
|
70
|
+
else
|
71
|
+
values << spv[:values] unless spv[:values].blank?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
sql[:predicates] = predicate
|
76
|
+
sql[:values] = values
|
77
|
+
sql
|
78
|
+
end
|
79
|
+
|
80
|
+
def search_model_class
|
81
|
+
return if parameter.search_model.blank? || parameter.search_method.blank?
|
82
|
+
search_model_class = parameter.search_model.safe_constantize
|
83
|
+
raise "Search model #{parameter.search_model} could not be found" if search_model_class.blank?
|
84
|
+
search_model_class
|
85
|
+
end
|
86
|
+
|
87
|
+
def search_model_attribute_method?
|
88
|
+
search_model_class && search_model_class.attribute_method?(parameter.search_method)
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_sql
|
92
|
+
sql = prepare_sql
|
93
|
+
if search_model_class && !search_model_attribute_method?
|
94
|
+
raise "Search model #{parameter.search_model} does not respond to search method #{parameter.search_method}" unless search_model_class.respond_to?(parameter.search_method)
|
95
|
+
sql = search_model_class.send(parameter.search_method, sql)
|
96
|
+
end
|
97
|
+
sql
|
98
|
+
end
|
99
|
+
|
100
|
+
def disabled?
|
101
|
+
return false unless persisted?
|
102
|
+
if parameter.blank?
|
103
|
+
warnings.add(:base, "Parameter has to be selected")
|
104
|
+
return true
|
105
|
+
elsif parameter.deleted?
|
106
|
+
warnings.add(:base, "Parameter has been deleted and has to be removed from the search")
|
107
|
+
return true
|
108
|
+
elsif search_parameter_values.blank? || (parameter.parameter_type.name == 'list' && search_parameter_values.select{|spv| spv.chosen?}.empty?)
|
109
|
+
warnings.add(:base, "Parameter value has to be selected")
|
110
|
+
return true
|
111
|
+
elsif deleted? || search_parameter_values.select{ |spv| spv.disabled?}.any?
|
112
|
+
return true
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
private
|
119
|
+
def update_associations
|
120
|
+
search_parameter_values.each do |r|
|
121
|
+
r.deleted_at = Time.now
|
122
|
+
r.save
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module Discerner
|
2
|
+
module Methods
|
3
|
+
module Models
|
4
|
+
module SearchParameterValue
|
5
|
+
def self.included(base)
|
6
|
+
base.send :include, SoftDelete
|
7
|
+
base.send :include, Warning
|
8
|
+
|
9
|
+
# Associations
|
10
|
+
base.send :belongs_to, :search_parameter, :inverse_of => :search_parameter_values
|
11
|
+
base.send :belongs_to, :parameter_value, :inverse_of => :search_parameter_values
|
12
|
+
base.send :belongs_to, :operator, :inverse_of => :search_parameter_values
|
13
|
+
|
14
|
+
# Scopes
|
15
|
+
base.send(:scope, :chosen, -> { base.where(:chosen => true) })
|
16
|
+
base.send(:scope, :ordered_by_display_order, -> { base.order('discerner_search_parameter_values.display_order ASC') })
|
17
|
+
|
18
|
+
#Validations
|
19
|
+
base.send :validate, :validate_operator
|
20
|
+
base.send :validates, :search_parameter, :presence => true
|
21
|
+
|
22
|
+
# Hooks
|
23
|
+
base.send :before_validation, :cleanup_parameter_values
|
24
|
+
base.send :after_commit, :destroy_if_deleted_parameter_value, :on => :update
|
25
|
+
|
26
|
+
# Whitelisting attributes
|
27
|
+
base.send :attr_accessible, :additional_value, :chosen, :display_order, :operator_id, :parameter_value_id, :search_parameter_id, :value, :parameter_value, :operator, :search_parameter
|
28
|
+
end
|
29
|
+
|
30
|
+
# Instance Methods
|
31
|
+
def initialize(*args)
|
32
|
+
super(*args)
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_sql
|
36
|
+
sql = {}
|
37
|
+
raise "Search operator has to be defined in order to run 'to_sql' method on search_parameter_value" if operator.blank?
|
38
|
+
case operator.operator_type
|
39
|
+
when 'comparison'
|
40
|
+
sql[:predicates] = "#{search_parameter.parameter.search_method} #{operator.symbol} ?"
|
41
|
+
sql[:values] = formatted_values.first
|
42
|
+
when 'range'
|
43
|
+
sql[:predicates] = "#{search_parameter.parameter.search_method} #{operator.symbol} ? and ?"
|
44
|
+
sql[:values] = formatted_values
|
45
|
+
when 'text_comparison'
|
46
|
+
sql[:predicates] = "#{search_parameter.parameter.search_method} #{operator.symbol} ?"
|
47
|
+
sql[:values] = "%#{formatted_values.first}%"
|
48
|
+
when 'presence'
|
49
|
+
sql[:predicates] = "#{search_parameter.parameter.search_method} #{operator.symbol}"
|
50
|
+
end
|
51
|
+
sql
|
52
|
+
end
|
53
|
+
|
54
|
+
def formatted_values
|
55
|
+
all_values = [value, additional_value].compact
|
56
|
+
case search_parameter.parameter.parameter_type.name
|
57
|
+
when 'date'
|
58
|
+
all_values.map{|v| v.to_date}
|
59
|
+
when 'numeric'
|
60
|
+
all_values.map{|v| v.to_f}
|
61
|
+
else
|
62
|
+
all_values
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def disabled?
|
67
|
+
return false unless persisted?
|
68
|
+
if parameter_value.blank? && value.blank? && operator && operator.operator_type != 'presence'
|
69
|
+
warnings.add(:base, "Parameter value has to be selected")
|
70
|
+
return true
|
71
|
+
end
|
72
|
+
if chosen? && parameter_value.blank? || parameter_value && parameter_value.deleted?
|
73
|
+
warnings.add(:base, "Parameter value has been deleted and has to be removed from the search")
|
74
|
+
return true
|
75
|
+
end
|
76
|
+
if search_parameter && search_parameter.parameter && search_parameter.parameter.parameter_type.name == 'date' && !validate_dates_format
|
77
|
+
warnings.add(:base, "Provided date is not valid")
|
78
|
+
return true
|
79
|
+
end
|
80
|
+
if parameter_value.blank? && search_parameter.parameter.parameter_type.name == 'combobox'
|
81
|
+
warnings.add(:base, "Parameter value has to be selected")
|
82
|
+
return true
|
83
|
+
end
|
84
|
+
warnings.clear
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
|
88
|
+
def validate_dates_format
|
89
|
+
validate_date(value) && validate_date(additional_value)
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
def destroy_if_deleted_parameter_value
|
94
|
+
return if parameter_value.blank? || search_parameter.blank? || search_parameter.parameter.blank? || search_parameter.parameter.parameter_type.blank?
|
95
|
+
#return unless ['list', 'combobox'].include?(search_parameter.parameter.parameter_type.name)
|
96
|
+
destroy if parameter_value.deleted? && search_parameter.parameter.parameter_type.name == 'list' && !chosen?
|
97
|
+
end
|
98
|
+
|
99
|
+
def validate_date(date)
|
100
|
+
begin
|
101
|
+
unless date.blank?
|
102
|
+
parsed_date = date.to_date
|
103
|
+
#http://www.karaszi.com/sqlserver/info_datetime.asp#Why1753
|
104
|
+
return false if parsed_date.year < 1753
|
105
|
+
end
|
106
|
+
rescue => e
|
107
|
+
return false
|
108
|
+
end
|
109
|
+
return true
|
110
|
+
end
|
111
|
+
|
112
|
+
def cleanup_parameter_values
|
113
|
+
if operator && operator.operator_type == 'presence'
|
114
|
+
self.value = nil
|
115
|
+
self.additional_value = nil
|
116
|
+
self.parameter_value = nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def validate_operator
|
121
|
+
if search_parameter && search_parameter.parameter && search_parameter.parameter.parameter_type && ['list', 'combobox'].include?(search_parameter.parameter.parameter_type.name)
|
122
|
+
self.operator = nil
|
123
|
+
else
|
124
|
+
errors.add(:base, "Operator has to be selected for parameter values that do not belong to list or combobox") if operator.blank?
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Discerner
|
2
|
+
module Methods
|
3
|
+
module Models
|
4
|
+
module SoftDelete
|
5
|
+
def self.included(base)
|
6
|
+
attr_accessor :soft_delete
|
7
|
+
base.send(:scope, :not_deleted, -> { base.where(:deleted_at => nil) })
|
8
|
+
end
|
9
|
+
|
10
|
+
def process_soft_delete
|
11
|
+
self.deleted_at = Time.zone.now
|
12
|
+
end
|
13
|
+
|
14
|
+
def soft_delete=(removed)
|
15
|
+
if (removed.is_a?(TrueClass) || removed.to_s == 't' || removed.to_s == '1')
|
16
|
+
process_soft_delete
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def soft_delete
|
21
|
+
!self.deleted_at.blank?
|
22
|
+
end
|
23
|
+
|
24
|
+
def soft_delete!
|
25
|
+
process_soft_delete
|
26
|
+
save!
|
27
|
+
end
|
28
|
+
|
29
|
+
def deleted?
|
30
|
+
!deleted_at.blank?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|