cullender 0.0.1
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.rdoc +3 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/cullender/application.js +13 -0
- data/app/assets/javascripts/cullender/rules.js +46 -0
- data/app/assets/stylesheets/cullender/application.css +13 -0
- data/app/assets/stylesheets/cullender/rules.css.scss +15 -0
- data/app/controllers/cullender/rules_controller.rb +68 -0
- data/app/controllers/cullender_controller.rb +105 -0
- data/app/helpers/cullender/rules_helper.rb +136 -0
- data/app/models/cullender/rule.rb +204 -0
- data/app/views/cullender/rules/_form.html.erb +20 -0
- data/app/views/cullender/rules/_trigger_fields.html.erb +19 -0
- data/app/views/cullender/rules/create.js.erb +3 -0
- data/app/views/cullender/rules/index.html.erb +25 -0
- data/app/views/cullender/rules/new.html.erb +1 -0
- data/app/views/cullender/rules/show.html.erb +3 -0
- data/config/locales/en.yml +12 -0
- data/config/routes.rb +4 -0
- data/lib/cullender.rb +96 -0
- data/lib/cullender/controllers/filter_logic.rb +89 -0
- data/lib/cullender/controllers/scoped_views.rb +17 -0
- data/lib/cullender/core_ext/hash.rb +1 -0
- data/lib/cullender/core_ext/hash/deep_delete.rb +13 -0
- data/lib/cullender/engine.rb +15 -0
- data/lib/cullender/engine/routes.rb +306 -0
- data/lib/cullender/mapping.rb +139 -0
- data/lib/cullender/version.rb +3 -0
- data/lib/generators/cullender/cullender_generator.rb +66 -0
- data/lib/generators/cullender/install_generator.rb +18 -0
- data/lib/generators/cullender/orm_helpers.rb +32 -0
- data/lib/generators/cullender/templates/cullender.rb +3 -0
- data/lib/generators/cullender/templates/cullender_migration.rb +13 -0
- data/lib/tasks/cullender_tasks.rake +4 -0
- data/spec/controllers/cullender/rules_controller_spec.rb +180 -0
- data/spec/cullender/controllers/filter_logic_spec.rb +233 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +17 -0
- data/spec/dummy/app/assets/stylesheets/application.css +14 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/events_controller.rb +60 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/event.rb +16 -0
- data/spec/dummy/app/views/cullender/rules/_form.html.erb +33 -0
- data/spec/dummy/app/views/cullender/rules/index.html.erb +24 -0
- data/spec/dummy/app/views/cullender/rules/new.html.erb +1 -0
- data/spec/dummy/app/views/cullender/rules/show.html.erb +3 -0
- data/spec/dummy/app/views/events/_form.html.erb +21 -0
- data/spec/dummy/app/views/events/edit.html.erb +6 -0
- data/spec/dummy/app/views/events/index.html.erb +27 -0
- data/spec/dummy/app/views/events/new.html.erb +5 -0
- data/spec/dummy/app/views/events/show.html.erb +10 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +23 -0
- data/spec/dummy/config/boot.rb +9 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +27 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cullender.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/cullender.en.yml +12 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/123344556676_create_cullender_tables.rb +12 -0
- data/spec/dummy/db/schema.rb +24 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +9987 -0
- data/spec/dummy/log/test.log +19786 -0
- data/spec/dummy/public/404.html +27 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/268a828ee4997cf5c19106e5f00fcfb8 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/56b2eb9b46b9aca7e86b5132ddf0d9de +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/750887406b3e8dacb2b03f986330932d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/750b42e431d194c41f5b1cde4a257e47 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/921642fe740290e9e5e88a706e5a562c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a967ed3fc5f8406f3ff72180775f1b40 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/ae74bf4fc3fd20e7f7b98860b8ef0f74 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c7dbd1f5acc2d5bc078363f4f3c70c54 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d995daf8d6f36c27b6e9d1b4672eaf1e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/helpers/cullender/rules_helper_spec.rb +360 -0
- data/spec/models/cullender/rule_spec.rb +425 -0
- data/spec/requests/rules_spec.rb +19 -0
- data/spec/spec_helper.rb +60 -0
- metadata +319 -0
@@ -0,0 +1,204 @@
|
|
1
|
+
module Cullender
|
2
|
+
class Rule < ActiveRecord::Base
|
3
|
+
|
4
|
+
before_create :add_event_percolation
|
5
|
+
before_update :modify_event_percolation
|
6
|
+
before_destroy :remove_event_percolation
|
7
|
+
|
8
|
+
|
9
|
+
serialize :triggers, Hash
|
10
|
+
|
11
|
+
validates :name, :presence => true, :uniqueness => true, :length => {
|
12
|
+
:minimum => 4,
|
13
|
+
:maximum => 20
|
14
|
+
}
|
15
|
+
|
16
|
+
# basic operators ["term", "terms", "string", "range", "prefix", "fuzzy"]
|
17
|
+
OPERATORS = {
|
18
|
+
"text_field" => {
|
19
|
+
I18n.t("cullender.operators.term") => "term",
|
20
|
+
I18n.t("cullender.operators.prefix") => "prefix"
|
21
|
+
},
|
22
|
+
"number_field" => {
|
23
|
+
I18n.t("cullender.operators.gt") => "gt",
|
24
|
+
I18n.t("cullender.operators.gte") => "gte",
|
25
|
+
I18n.t("cullender.operators.lt") => "lt",
|
26
|
+
I18n.t("cullender.operators.lte") => "lte",
|
27
|
+
I18n.t("cullender.operators.eq") => "term"
|
28
|
+
},
|
29
|
+
"range_field" => {
|
30
|
+
I18n.t("cullender.operators.gt") => "gt",
|
31
|
+
I18n.t("cullender.operators.gte") => "gte",
|
32
|
+
I18n.t("cullender.operators.lt") => "lt",
|
33
|
+
I18n.t("cullender.operators.lte") => "lte",
|
34
|
+
I18n.t("cullender.operators.eq") => "term"
|
35
|
+
},
|
36
|
+
"date" => {
|
37
|
+
I18n.t("cullender.operators.from") => "from",
|
38
|
+
I18n.t("cullender.operators.to") => "to"
|
39
|
+
},
|
40
|
+
"datetime" => {
|
41
|
+
I18n.t("cullender.operators.from") => "from",
|
42
|
+
I18n.t("cullender.operators.to") => "to"
|
43
|
+
},
|
44
|
+
"select" => {
|
45
|
+
I18n.t("cullender.operators.is") => "term",
|
46
|
+
I18n.t("cullender.operators.is_not") => "term"
|
47
|
+
},
|
48
|
+
"check_box" => {
|
49
|
+
I18n.t("cullender.operators.eq") => "is"
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
FILTER_MAP = {
|
54
|
+
"term" => "==",
|
55
|
+
"prefix" => "starts with",
|
56
|
+
"gt" => ">",
|
57
|
+
"gte" => ">=",
|
58
|
+
"lt" => "<",
|
59
|
+
"lte" => "<=",
|
60
|
+
"from" => ">=",
|
61
|
+
"to" => "<="
|
62
|
+
}
|
63
|
+
|
64
|
+
FIELD_TYPE_MAP = {
|
65
|
+
'string' => 'text_field',
|
66
|
+
'integer' => 'number_field',
|
67
|
+
'long' => 'number_field',
|
68
|
+
'double' => 'number_field',
|
69
|
+
'float' => 'number_field',
|
70
|
+
'date' => 'date',
|
71
|
+
'boolean' => 'check_box'
|
72
|
+
}
|
73
|
+
|
74
|
+
|
75
|
+
# This method searches elastic search for events that match this specific
|
76
|
+
def fire(event)
|
77
|
+
event.add_labels(self.labels) unless self.labels.empty?
|
78
|
+
# send any notifications
|
79
|
+
end
|
80
|
+
|
81
|
+
# converts the current rule to a proc accepting an an elastic search query object
|
82
|
+
def to_query_proc
|
83
|
+
Proc.new do
|
84
|
+
self.to_query
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_query
|
89
|
+
query = ::Tire::Search::Query.new
|
90
|
+
if triggers.present?
|
91
|
+
|
92
|
+
# check if there is only one field
|
93
|
+
count = number_of_fields
|
94
|
+
if count > 1
|
95
|
+
# complex operators ["boolean", "filtered", "dis_max", "nested"]
|
96
|
+
convert_to_boolean(query)
|
97
|
+
elsif count == 1
|
98
|
+
query = convert_to_basic_query(query, triggers.first[0], triggers.first[1])
|
99
|
+
else
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
query
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
def convert_to_boolean(query, params = self.triggers)
|
108
|
+
query.boolean do |bool|
|
109
|
+
params.each do |key, values|
|
110
|
+
if key.to_i > 0
|
111
|
+
bool.should do |q|
|
112
|
+
convert_to_boolean(q, values)
|
113
|
+
end
|
114
|
+
else
|
115
|
+
bool.must do |q|
|
116
|
+
convert_to_basic_query(q, key, values)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
query
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
# def to_filter
|
127
|
+
# search = ::Tire::Search::Search.new
|
128
|
+
# filters_to_or = []
|
129
|
+
# search.query.all
|
130
|
+
# triggers.each do |key, value|
|
131
|
+
# if value.has_key?("o") && value.has_key?("v")
|
132
|
+
# search.filter :term, key.to_sym => value["v"]
|
133
|
+
# else
|
134
|
+
# f = self.to_search(::Tire::Search::Search.new, value).to_hash
|
135
|
+
# filters_to_or << f[:filter]
|
136
|
+
# end
|
137
|
+
# end
|
138
|
+
# search.filter :or, filters_to_or unless filters_to_or.empty?
|
139
|
+
# search
|
140
|
+
# end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def add_event_percolation
|
145
|
+
begin
|
146
|
+
# debugger
|
147
|
+
response = Event.index.register_percolator_query(self.name, :query => self.to_query.to_hash)
|
148
|
+
!response.nil?
|
149
|
+
rescue Exception => e
|
150
|
+
false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def modify_event_percolation
|
155
|
+
begin
|
156
|
+
response = Event.index.unregister_percolator_query(self.name)
|
157
|
+
response = Event.index.register_percolator_query(self.name, :query => self.to_query.to_hash)
|
158
|
+
!response.nil?
|
159
|
+
rescue Exception => e
|
160
|
+
false
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def remove_event_percolation
|
165
|
+
begin
|
166
|
+
response = Event.index.unregister_percolator_query(self.name, :query => self.to_query.to_hash)
|
167
|
+
!response.nil?
|
168
|
+
rescue Exception => e
|
169
|
+
false
|
170
|
+
end
|
171
|
+
end
|
172
|
+
private
|
173
|
+
|
174
|
+
##
|
175
|
+
# Calculate the number of fields in the triggers hash
|
176
|
+
def number_of_fields(params = self.triggers)
|
177
|
+
if params.present?
|
178
|
+
params.values.inject(0) do |sum, value|
|
179
|
+
if value.is_a?(Hash)
|
180
|
+
# puts value.keys.inspect
|
181
|
+
sum + (value.keys.include?("o") ? 1 : number_of_fields(value) )
|
182
|
+
else
|
183
|
+
sum + 1
|
184
|
+
end
|
185
|
+
end
|
186
|
+
else
|
187
|
+
0
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def convert_to_basic_query(query, field_name, params = {})
|
192
|
+
# basic operators ["term", "terms", "string", "range", "prefix", "fuzzy"]
|
193
|
+
if (query.is_a?(Tire::Search::Query))
|
194
|
+
operator = params["o"]
|
195
|
+
value = params["v"]
|
196
|
+
query.send(operator.to_sym, field_name, value)
|
197
|
+
else
|
198
|
+
raise ArgumentError, "Argument is not a Tire::Search::Search."
|
199
|
+
end
|
200
|
+
query
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%= simple_form_for rule, :html => { :class => "form-horizontal" } do |f| %>
|
2
|
+
<%= f.error_notification %>
|
3
|
+
<div class="form-inputs">
|
4
|
+
<fieldset id="rule">
|
5
|
+
<legend>Rule Description</legend>
|
6
|
+
<%= f.input :name %>
|
7
|
+
<%= f.input :description %>
|
8
|
+
<%= f.association :table, :prompt => "Select Type" %>
|
9
|
+
</fieldset>
|
10
|
+
|
11
|
+
<fieldset id="triggers" class="filters">
|
12
|
+
<legend>Triggers</legend>
|
13
|
+
<%= render 'trigger_fields', :locals => {properties: Event.properties} %>
|
14
|
+
</fieldset>
|
15
|
+
|
16
|
+
<div class="form-actions">
|
17
|
+
<%= f.error :base %>
|
18
|
+
<%= f.button :submit %>
|
19
|
+
</div>
|
20
|
+
<% end %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div id="cullender_triggers">
|
2
|
+
<% if params.has_key?("triggers") || params.has_key?("rule") && params["rule"].has_key?("triggers") %>
|
3
|
+
<%= render_property_tree("rule[triggers]", mapping, extract_triggers(params)) do |html, at_end, hierarchy| %>
|
4
|
+
<div class="controls">
|
5
|
+
<%= html %>
|
6
|
+
</div>
|
7
|
+
<div class="controls">
|
8
|
+
<% if at_end < 0 %>
|
9
|
+
<%= cullender_collection_or_select(mapping.keys, hierarchy) %>
|
10
|
+
<% else %>
|
11
|
+
<%= cullender_collection_and_select(mapping.keys, hierarchy) %>
|
12
|
+
<% end -%>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
<% end %>
|
16
|
+
<div class="controls">
|
17
|
+
<%= cullender_collection_or_select(mapping.keys, [], {:base => true}) %>
|
18
|
+
</div>
|
19
|
+
</div>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<h1>Listing rules</h1>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<thead>
|
5
|
+
<tr>
|
6
|
+
<th>Name</th>
|
7
|
+
<th>Enabled</th>
|
8
|
+
<th></th>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
|
12
|
+
<tbody>
|
13
|
+
<% @rules.each do |rule| %>
|
14
|
+
<tr>
|
15
|
+
<td><%= link_to rule.name, rule %></td>
|
16
|
+
<td><%= link_to 'Edit', rule %></td>
|
17
|
+
<td><%= link_to 'Destroy', rule, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
18
|
+
</tr>
|
19
|
+
<% end %>
|
20
|
+
</tbody>
|
21
|
+
</table>
|
22
|
+
|
23
|
+
<br />
|
24
|
+
|
25
|
+
<%= link_to 'New Rule', new_rule_path %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render 'form', :rule => @rule %>
|
data/config/routes.rb
ADDED
data/lib/cullender.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require "tire"
|
2
|
+
require "cullender/core_ext/hash"
|
3
|
+
|
4
|
+
module Rails
|
5
|
+
module Generators
|
6
|
+
module Migration
|
7
|
+
module ClassMethods
|
8
|
+
def next_migration_number(dirname) #:nodoc:
|
9
|
+
"123344556676"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
module Cullender
|
18
|
+
|
19
|
+
module Controllers
|
20
|
+
autoload :ScopedViews, 'cullender/controllers/scoped_views'
|
21
|
+
autoload :FilterLogic, "cullender/controllers/filter_logic"
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
# The parent controller all Devise controllers inherits from.
|
26
|
+
# Defaults to ApplicationController. This should be set early
|
27
|
+
# in the initialization process and should be set to a string.
|
28
|
+
mattr_accessor :parent_controller
|
29
|
+
@@parent_controller = "ApplicationController"
|
30
|
+
|
31
|
+
# The router Devise should use to generate routes. Defaults
|
32
|
+
# to :main_app. Should be overriden by engines in order
|
33
|
+
# to provide custom routes.
|
34
|
+
mattr_accessor :router_name
|
35
|
+
@@router_name = nil
|
36
|
+
|
37
|
+
# Define a set of modules that are called when a mapping is added.
|
38
|
+
mattr_reader :helpers
|
39
|
+
@@helpers = Set.new
|
40
|
+
# @@helpers << Cullender::Controllers::Helpers
|
41
|
+
|
42
|
+
# Store scopes mappings.
|
43
|
+
mattr_reader :mappings
|
44
|
+
@@mappings = ActiveSupport::OrderedHash.new
|
45
|
+
|
46
|
+
|
47
|
+
# Scoped views. Since it relies on fallbacks to render default views, it's
|
48
|
+
# turned off by default.
|
49
|
+
mattr_accessor :scoped_views
|
50
|
+
@@scoped_views = false
|
51
|
+
|
52
|
+
# Default way to setup Cullender. Run rails generate cullender:install to create
|
53
|
+
# a fresh initializer with all configuration values.
|
54
|
+
def self.setup
|
55
|
+
yield self
|
56
|
+
end
|
57
|
+
|
58
|
+
# Regenerates url helpers considering Devise.mapping
|
59
|
+
def self.regenerate_helpers!
|
60
|
+
# Devise::Controllers::UrlHelpers.remove_helpers!
|
61
|
+
# Devise::Controllers::UrlHelpers.generate_helpers!
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
# Small method that adds a mapping to Devise.
|
66
|
+
def self.add_mapping(resource, options)
|
67
|
+
mapping = Cullender::Mapping.new(resource, options)
|
68
|
+
@@mappings[mapping.name] = mapping
|
69
|
+
@@default_scope ||= mapping.name
|
70
|
+
@@helpers.each { |h| h.define_helpers(mapping) }
|
71
|
+
mapping
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
class Getter
|
76
|
+
def initialize name
|
77
|
+
@name = name
|
78
|
+
end
|
79
|
+
|
80
|
+
def get
|
81
|
+
ActiveSupport::Dependencies.constantize(@name)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.ref(arg)
|
86
|
+
if defined?(ActiveSupport::Dependencies::ClassCache)
|
87
|
+
ActiveSupport::Dependencies::reference(arg)
|
88
|
+
Getter.new(arg)
|
89
|
+
else
|
90
|
+
ActiveSupport::Dependencies.ref(arg)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
require 'cullender/mapping'
|
96
|
+
require "cullender/engine"
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Cullender
|
2
|
+
module Controllers
|
3
|
+
module FilterLogic
|
4
|
+
def add_or_filter(key, params, field, should_raise = false)
|
5
|
+
if params.present? && params.has_key?(key)
|
6
|
+
if should_raise
|
7
|
+
params[key] = {1 => params[key], 2 => add_operator(field)}
|
8
|
+
else
|
9
|
+
idx = params[key].keys.last.to_i + 1
|
10
|
+
params[key].deep_merge!({idx => add_operator(field)})
|
11
|
+
end
|
12
|
+
else
|
13
|
+
if should_raise
|
14
|
+
params[key] = add_operator(field)
|
15
|
+
else
|
16
|
+
params[key] = add_operator(field)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_and_filter(key, params, field)
|
22
|
+
clean_field(field) unless field.is_a? String
|
23
|
+
if params.present? && params.has_key?(key)
|
24
|
+
params[key].deep_merge!(add_operator(field))
|
25
|
+
else
|
26
|
+
params[key] = add_operator(field)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def clean_field(field)
|
31
|
+
|
32
|
+
field.each do |key, value|
|
33
|
+
if value.is_a?(Hash)
|
34
|
+
clean_field(value)
|
35
|
+
else
|
36
|
+
field.delete(key) if value.blank?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def remove_and_filter(key, params, field)
|
42
|
+
if params.present? && params.has_key?(key)
|
43
|
+
if field.is_a? String
|
44
|
+
params[key].delete(field)
|
45
|
+
else
|
46
|
+
params[key].deep_delete(field)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_operator(field)
|
52
|
+
if field.is_a?(Hash)
|
53
|
+
hash = {}
|
54
|
+
field.each do |key, value|
|
55
|
+
if ["o", "v"].include?(key)
|
56
|
+
hash = field
|
57
|
+
break
|
58
|
+
else
|
59
|
+
hash.merge!({key => add_operator(value)}) unless ["o", "v"].include?(key)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
elsif
|
63
|
+
hash = {field => {"o" => nil}}
|
64
|
+
end
|
65
|
+
hash
|
66
|
+
end
|
67
|
+
|
68
|
+
def apply_filter_actions(name, filter_params, params)
|
69
|
+
# debugger
|
70
|
+
updated = false
|
71
|
+
if params.has_key?("or") && (params["or"].has_key?("commit") || params["or"].has_key?("raise"))
|
72
|
+
nfilter = params.delete("or")
|
73
|
+
should_raise = nfilter.has_key?("raise")
|
74
|
+
add_or_filter(name, filter_params, should_raise ? nfilter["raise_field"] : nfilter["field"], should_raise) if (nfilter["field"].present? || nfilter["raise_field"].present?)
|
75
|
+
updated = true
|
76
|
+
elsif params.has_key?("and") && params["and"].has_key?("commit")
|
77
|
+
nfilter = params.delete("and")
|
78
|
+
add_and_filter(name, filter_params, nfilter["field"]) if nfilter["field"].present?
|
79
|
+
updated = true
|
80
|
+
elsif params.has_key?("remove")
|
81
|
+
nfilter = params.delete("remove")
|
82
|
+
remove_and_filter(name, filter_params, nfilter)
|
83
|
+
updated = true
|
84
|
+
end
|
85
|
+
updated
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|