super 0.0.14 → 0.18.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 +4 -4
- data/README.md +2 -2
- data/app/assets/javascripts/super/application.js +148 -15
- data/app/assets/stylesheets/super/application.css +15 -22
- data/app/controllers/super/application_controller.rb +44 -42
- data/app/controllers/super/substructure_controller.rb +313 -0
- data/app/helpers/super/form_builder_helper.rb +7 -0
- data/app/views/layouts/super/application.html.erb +3 -21
- data/app/views/super/application/_collection_header.html.erb +2 -2
- data/app/views/super/application/_display_actions.html.erb +1 -1
- data/app/views/super/application/_display_index.html.erb +2 -2
- data/app/views/super/application/_display_show.html.erb +1 -1
- data/app/views/super/application/_filter.html.erb +62 -2
- data/app/views/super/application/_form_field.html.erb +5 -0
- data/app/views/super/application/_member_header.html.erb +2 -2
- data/app/views/super/application/_pagination.html.erb +1 -1
- data/app/views/super/application/_site_footer.html.erb +3 -0
- data/app/views/super/application/_site_header.html.erb +17 -0
- data/app/views/super/application/_sort_expression.html.erb +2 -2
- data/app/views/super/application/index.csv.erb +14 -0
- data/app/views/super/feather/README.md +0 -1
- data/frontend/super-frontend/dist/application.css +15 -22
- data/frontend/super-frontend/dist/application.js +148 -15
- data/lib/generators/super/install/install_generator.rb +0 -16
- data/lib/generators/super/install/templates/base_controller.rb.tt +0 -8
- data/lib/generators/super/resource/templates/resources_controller.rb.tt +4 -4
- data/lib/super/action_inquirer.rb +18 -3
- data/lib/super/badge.rb +60 -0
- data/lib/super/cheat.rb +6 -6
- data/lib/super/display/guesser.rb +1 -1
- data/lib/super/display/schema_types.rb +49 -1
- data/lib/super/display.rb +2 -1
- data/lib/super/error.rb +3 -0
- data/lib/super/filter/form_object.rb +74 -48
- data/lib/super/filter/guesser.rb +2 -0
- data/lib/super/filter/operator.rb +90 -64
- data/lib/super/filter/schema_types.rb +63 -80
- data/lib/super/filter.rb +1 -1
- data/lib/super/form/builder.rb +30 -39
- data/lib/super/form/field_transcript.rb +43 -0
- data/lib/super/form/guesser.rb +4 -4
- data/lib/super/form/schema_types.rb +66 -22
- data/lib/super/link.rb +2 -2
- data/lib/super/pagination.rb +2 -44
- data/lib/super/reset.rb +25 -0
- data/lib/super/schema.rb +4 -0
- data/lib/super/useful/builder.rb +4 -4
- data/lib/super/version.rb +1 -1
- data/lib/super.rb +3 -1
- data/lib/tasks/super/cheat.rake +1 -1
- metadata +25 -19
- data/app/views/super/application/_filter_type_select.html.erb +0 -21
- data/app/views/super/application/_filter_type_text.html.erb +0 -18
- data/app/views/super/application/_filter_type_timestamp.html.erb +0 -24
- data/app/views/super/application/_form_field_checkbox.html.erb +0 -1
- data/app/views/super/application/_form_field_flatpickr_date.html.erb +0 -8
- data/app/views/super/application/_form_field_flatpickr_datetime.html.erb +0 -8
- data/app/views/super/application/_form_field_flatpickr_time.html.erb +0 -8
- data/app/views/super/application/_form_field_rich_text_area.html.erb +0 -1
- data/app/views/super/application/_form_field_select.html.erb +0 -1
- data/app/views/super/application/_form_field_text.html.erb +0 -1
- data/app/views/super/feather/_chevron_down.html +0 -1
- data/docs/cheat.md +0 -41
- data/lib/super/controls/optional.rb +0 -113
- data/lib/super/controls/steps.rb +0 -106
- data/lib/super/controls/view.rb +0 -55
- data/lib/super/controls.rb +0 -22
@@ -19,12 +19,27 @@ module Super
|
|
19
19
|
#
|
20
20
|
def self.default_for_resources
|
21
21
|
{
|
22
|
-
read
|
23
|
-
write
|
24
|
-
delete
|
22
|
+
"read" => %w[index show new edit],
|
23
|
+
"write" => %w[create update destroy],
|
24
|
+
"delete" => %w[destroy],
|
25
25
|
}
|
26
26
|
end
|
27
27
|
|
28
|
+
# @return [ActionInquirer]
|
29
|
+
def self.index!; new(default_for_resources, "index"); end
|
30
|
+
# @return [ActionInquirer]
|
31
|
+
def self.show!; new(default_for_resources, "show"); end
|
32
|
+
# @return [ActionInquirer]
|
33
|
+
def self.new!; new(default_for_resources, "new"); end
|
34
|
+
# @return [ActionInquirer]
|
35
|
+
def self.edit!; new(default_for_resources, "edit"); end
|
36
|
+
# @return [ActionInquirer]
|
37
|
+
def self.create!; new(default_for_resources, "create"); end
|
38
|
+
# @return [ActionInquirer]
|
39
|
+
def self.update!; new(default_for_resources, "update"); end
|
40
|
+
# @return [ActionInquirer]
|
41
|
+
def self.destroy!; new(default_for_resources, "destroy"); end
|
42
|
+
|
28
43
|
def initialize(categories_and_their_actions, action)
|
29
44
|
@categories = categories_and_their_actions.keys.map(&:to_s)
|
30
45
|
@actions = categories_and_their_actions.values.flatten.uniq.map(&:to_s)
|
data/lib/super/badge.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Super
|
4
|
+
class Badge
|
5
|
+
STYLES = {
|
6
|
+
light: "bg-gray-100 text-black",
|
7
|
+
dark: "bg-gray-900 text-white",
|
8
|
+
red: "bg-red-700 text-white",
|
9
|
+
yellow: "bg-yellow-400 text-black",
|
10
|
+
green: "bg-green-700 text-white",
|
11
|
+
blue: "bg-blue-700 text-white",
|
12
|
+
purple: "bg-purple-800 text-white",
|
13
|
+
}
|
14
|
+
|
15
|
+
def initialize(text, styles: nil)
|
16
|
+
@text = text
|
17
|
+
@requested_styles = Array(styles.presence).flatten
|
18
|
+
end
|
19
|
+
|
20
|
+
def styles
|
21
|
+
return @styles if instance_variable_defined?(:@styles)
|
22
|
+
@styles =
|
23
|
+
if requested_styles.delete(:reset)
|
24
|
+
[]
|
25
|
+
else
|
26
|
+
COMMON_STYLES
|
27
|
+
end
|
28
|
+
|
29
|
+
if requested_styles.empty?
|
30
|
+
@styles += [STYLES[:light]]
|
31
|
+
else
|
32
|
+
requested_styles.each do |style|
|
33
|
+
@styles +=
|
34
|
+
if STYLES.key?(style)
|
35
|
+
[STYLES[style]]
|
36
|
+
else
|
37
|
+
[style]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
@styles
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
ActionController::Base.helpers.content_tag(
|
47
|
+
:span,
|
48
|
+
@text,
|
49
|
+
class: styles.join(" ")
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
COMMON_STYLES = %w[rounded px-2 py-1 text-xs leading-none font-bold]
|
56
|
+
private_constant :COMMON_STYLES
|
57
|
+
|
58
|
+
attr_reader :requested_styles
|
59
|
+
end
|
60
|
+
end
|
data/lib/super/cheat.rb
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
module Super
|
4
4
|
class Cheat
|
5
|
-
def
|
6
|
-
paths = %w[
|
5
|
+
def controller
|
6
|
+
paths = %w[../../app/controllers/super/substructure_controller.rb]
|
7
7
|
methods =
|
8
8
|
paths
|
9
|
-
.map { |f| File.read(File.
|
10
|
-
.flat_map { |content| content.scan(/^\s+def .*$/) }
|
11
|
-
.map { |method| method.strip.sub(/^def /, "#") }
|
9
|
+
.map { |f| File.read(File.expand_path(f, __dir__)) }
|
10
|
+
.flat_map { |content| content.scan(/^\s+(?:helper_method )?def .*$/) }
|
11
|
+
.map { |method| method.strip.sub(/^(?:helper_method )?def /, "#") }
|
12
12
|
|
13
|
-
puts "== Super::
|
13
|
+
puts "== Super::ApplicationController"
|
14
14
|
puts methods.join("\n")
|
15
15
|
end
|
16
16
|
end
|
@@ -61,6 +61,47 @@ module Super
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
class Badge
|
65
|
+
extend Useful::Builder
|
66
|
+
|
67
|
+
def initialize(builder)
|
68
|
+
@builder = builder
|
69
|
+
@whens = {}
|
70
|
+
format_for_lookup(&:itself)
|
71
|
+
format_for_display(&:itself)
|
72
|
+
end
|
73
|
+
|
74
|
+
builder_with_block def when(*patterns, &block)
|
75
|
+
patterns.each do |pattern|
|
76
|
+
@whens[pattern] = block
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
builder_with_block def else(&block)
|
81
|
+
@else = block
|
82
|
+
end
|
83
|
+
|
84
|
+
builder_with_block def format_for_lookup(&block)
|
85
|
+
@format_for_lookup = block
|
86
|
+
end
|
87
|
+
|
88
|
+
builder_with_block def format_for_display(&block)
|
89
|
+
@format_for_display = block
|
90
|
+
end
|
91
|
+
|
92
|
+
def build
|
93
|
+
@builder.transform do |value|
|
94
|
+
lookup_value = @format_for_lookup.call(value)
|
95
|
+
block = @whens[lookup_value] || @else
|
96
|
+
Super::Badge.new(
|
97
|
+
@format_for_display.call(value),
|
98
|
+
styles: block&.call
|
99
|
+
)
|
100
|
+
end
|
101
|
+
@builder.build
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
64
105
|
def initialize(fields:)
|
65
106
|
@actions_called = false
|
66
107
|
@fields = fields
|
@@ -89,7 +130,6 @@ module Super
|
|
89
130
|
end
|
90
131
|
|
91
132
|
def string; real(&:to_s); end
|
92
|
-
alias text string
|
93
133
|
|
94
134
|
def timestamp; real(&:to_s); end
|
95
135
|
def time; real { |value| value.strftime("%H:%M:%S") }; end
|
@@ -100,6 +140,14 @@ module Super
|
|
100
140
|
end
|
101
141
|
end
|
102
142
|
|
143
|
+
def badge(*builder_methods)
|
144
|
+
builder_methods = %i[real ignore_nil column] if builder_methods.empty?
|
145
|
+
builder = builder_methods.each_with_object(Builder.new) do |builder_method, builder|
|
146
|
+
builder.public_send(builder_method)
|
147
|
+
end
|
148
|
+
Badge.new(builder)
|
149
|
+
end
|
150
|
+
|
103
151
|
def actions
|
104
152
|
@actions_called = true
|
105
153
|
Builder.new.computed.none.transform do
|
data/lib/super/display.rb
CHANGED
@@ -32,10 +32,11 @@ module Super
|
|
32
32
|
yield(@fields, @schema_types)
|
33
33
|
end
|
34
34
|
|
35
|
-
def apply(action:)
|
35
|
+
def apply(action:, format:)
|
36
36
|
@action_inquirer = action
|
37
37
|
return self if !@action_inquirer.index?
|
38
38
|
return self if @schema_types.actions_called?
|
39
|
+
return self if !format.html?
|
39
40
|
@fields[:actions] = @schema_types.actions
|
40
41
|
self
|
41
42
|
end
|
data/lib/super/error.rb
CHANGED
@@ -28,6 +28,9 @@ module Super
|
|
28
28
|
# a more specific error
|
29
29
|
class Initalization < Error; end
|
30
30
|
class ArgumentError < Error; end
|
31
|
+
class AlreadyRegistered < Error; end
|
32
|
+
class AlreadyTranscribed < Error; end
|
33
|
+
class NotImplementedError < Error; end
|
31
34
|
|
32
35
|
class Enum < Error
|
33
36
|
class ImpossibleValue < Enum; end
|
@@ -3,58 +3,95 @@
|
|
3
3
|
module Super
|
4
4
|
class Filter
|
5
5
|
class FormObject
|
6
|
-
class
|
7
|
-
def initialize(
|
8
|
-
@
|
6
|
+
class AttributeForm
|
7
|
+
def initialize(model:, field_name:, operators:, params:)
|
8
|
+
@model = model
|
9
9
|
@field_name = field_name
|
10
|
-
@
|
11
|
-
@params = params
|
10
|
+
@operators = operators
|
11
|
+
@params = params || {}
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :model
|
15
|
+
attr_reader :field_name
|
16
|
+
attr_reader :operators
|
17
|
+
attr_reader :params
|
18
|
+
|
19
|
+
def each_operator
|
20
|
+
return enum_for(:each_operator) if !block_given?
|
21
|
+
|
22
|
+
@operators.each do |operator|
|
23
|
+
operator_form = OperatorForm.new(
|
24
|
+
operator: operator,
|
25
|
+
params: @params[operator.identifier]
|
26
|
+
)
|
27
|
+
|
28
|
+
yield(operator_form)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def humanized_attribute_name
|
33
|
+
@model.human_attribute_name(@field_name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class OperatorForm
|
38
|
+
NULLARY = :_apply
|
39
|
+
|
40
|
+
def initialize(operator:, params:)
|
41
|
+
@operator = operator
|
42
|
+
@params = params || {}
|
43
|
+
query_parameter_keys = operator.query_parameter_keys
|
44
|
+
query_parameter_keys = [NULLARY] if query_parameter_keys.empty?
|
12
45
|
@specified_values =
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
query_field_name,
|
17
|
-
(params || {})[query_field_name],
|
18
|
-
]
|
19
|
-
end
|
20
|
-
.to_h
|
46
|
+
query_parameter_keys
|
47
|
+
.map { |key| [key, @params[key].presence&.strip] }
|
48
|
+
.to_h
|
21
49
|
|
22
50
|
@specified_values.each do |key, value|
|
23
51
|
define_singleton_method(key) { value }
|
24
52
|
end
|
25
53
|
end
|
26
54
|
|
27
|
-
|
28
|
-
|
29
|
-
|
55
|
+
def specified?
|
56
|
+
@specified_values.any? { |_key, value| value }
|
57
|
+
end
|
58
|
+
|
59
|
+
attr_reader :operator
|
30
60
|
attr_reader :specified_values
|
31
61
|
|
32
|
-
def
|
33
|
-
|
62
|
+
def identifier
|
63
|
+
@operator.identifier
|
34
64
|
end
|
35
65
|
|
36
|
-
def
|
37
|
-
|
38
|
-
.map { |o| [o.name, o.identifier] }
|
39
|
-
.to_h
|
40
|
-
end
|
66
|
+
def each_field
|
67
|
+
return enum_for(:each_field) if !block_given?
|
41
68
|
|
42
|
-
|
43
|
-
|
69
|
+
@specified_values.each do |key, _value|
|
70
|
+
yield(key)
|
71
|
+
end
|
44
72
|
end
|
45
73
|
end
|
46
74
|
|
47
75
|
def initialize(model:, params:, schema:)
|
48
76
|
@model = model
|
49
|
-
@params = params
|
77
|
+
@params = params || {}
|
50
78
|
@schema = schema
|
51
79
|
|
52
80
|
@form_fields = {}
|
53
81
|
end
|
54
82
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
83
|
+
def each_attribute
|
84
|
+
return enum_for(:each_attribute) if !block_given?
|
85
|
+
|
86
|
+
@schema.fields.each do |field_name, field_operators|
|
87
|
+
attribute_form = AttributeForm.new(
|
88
|
+
model: @model,
|
89
|
+
field_name: field_name,
|
90
|
+
operators: field_operators,
|
91
|
+
params: @params[field_name]
|
92
|
+
)
|
93
|
+
|
94
|
+
yield(attribute_form)
|
58
95
|
end
|
59
96
|
end
|
60
97
|
|
@@ -63,32 +100,21 @@ module Super
|
|
63
100
|
end
|
64
101
|
|
65
102
|
def apply_changes(relation)
|
66
|
-
|
67
|
-
|
68
|
-
|
103
|
+
each_attribute do |attribute_form|
|
104
|
+
attribute_form.each_operator do |operator_form|
|
105
|
+
next if operator_form.specified_values.values.map(&:to_s).map(&:presence).none?
|
69
106
|
|
70
|
-
|
71
|
-
|
107
|
+
operator_behavior = operator_form.operator.behavior
|
108
|
+
updated_relation = operator_behavior.call(relation, attribute_form.field_name, **operator_form.specified_values)
|
72
109
|
|
73
|
-
|
74
|
-
|
110
|
+
if updated_relation.is_a?(ActiveRecord::Relation)
|
111
|
+
relation = updated_relation
|
112
|
+
end
|
75
113
|
end
|
76
114
|
end
|
77
115
|
|
78
116
|
relation
|
79
117
|
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def form_field_for(field_name)
|
84
|
-
@form_fields[field_name] ||=
|
85
|
-
FilterFormField.new(
|
86
|
-
humanized_field_name: @model.human_attribute_name(field_name),
|
87
|
-
field_name: field_name,
|
88
|
-
type: @schema.fields[field_name],
|
89
|
-
params: (@params || {})[field_name]
|
90
|
-
)
|
91
|
-
end
|
92
118
|
end
|
93
119
|
end
|
94
120
|
end
|
data/lib/super/filter/guesser.rb
CHANGED
@@ -2,100 +2,126 @@
|
|
2
2
|
|
3
3
|
module Super
|
4
4
|
class Filter
|
5
|
-
|
6
|
-
class Definition
|
7
|
-
def initialize(identifier, name, filter)
|
8
|
-
@identifier = identifier
|
9
|
-
@name = name
|
10
|
-
@filter = filter
|
11
|
-
end
|
12
|
-
|
13
|
-
attr_reader :identifier
|
14
|
-
attr_reader :name
|
15
|
-
|
16
|
-
def filter(*args)
|
17
|
-
@filter.call(args)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
5
|
+
class Operator
|
21
6
|
class << self
|
22
7
|
def registry
|
23
8
|
@registry ||= {}
|
24
9
|
end
|
25
10
|
|
26
|
-
def
|
27
|
-
|
28
|
-
registry["between"],
|
29
|
-
]
|
11
|
+
def [](key)
|
12
|
+
registry.fetch(key.to_s)
|
30
13
|
end
|
31
14
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
15
|
+
def register(identifier, operator)
|
16
|
+
identifier = identifier.to_s
|
17
|
+
if registry.key?(identifier)
|
18
|
+
raise Error::AlreadyRegistered, "Already registered: #{identifier}"
|
19
|
+
end
|
20
|
+
|
21
|
+
registry[identifier] = operator
|
37
22
|
end
|
38
23
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
registry["contain"],
|
44
|
-
registry["ncontain"],
|
45
|
-
registry["start"],
|
46
|
-
registry["end"],
|
47
|
-
]
|
24
|
+
def define(identifier, display, &block)
|
25
|
+
operator = new(identifier, display, &block).freeze
|
26
|
+
register(identifier, operator)
|
27
|
+
operator
|
48
28
|
end
|
29
|
+
end
|
49
30
|
|
50
|
-
|
51
|
-
|
52
|
-
|
31
|
+
def initialize(identifier, display, &behavior)
|
32
|
+
@identifier = identifier.to_s
|
33
|
+
@humanized_operator_name = display
|
34
|
+
self.behavior = behavior
|
35
|
+
end
|
36
|
+
|
37
|
+
def behavior=(behavior)
|
38
|
+
behavior_params = behavior.parameters
|
39
|
+
if behavior_params.size < 2
|
40
|
+
raise Error::ArgumentError, "Operator behavior must include `column_name` and `relation`"
|
41
|
+
end
|
42
|
+
if behavior_params[0][0] != :req && behavior_params[0][0] != :opt
|
43
|
+
raise Error::ArgumentError, "First argument `relation` must be a required, positional argument"
|
44
|
+
end
|
45
|
+
if behavior_params[1][0] != :req && behavior_params[1][0] != :opt
|
46
|
+
raise Error::ArgumentError, "Second argument `column_name` must be a required, positional argument"
|
47
|
+
end
|
48
|
+
if !behavior_params[2..-1].all? { |(type, _name)| type == :keyreq }
|
49
|
+
raise Error::ArgumentError, "All query parameter keys must be required, keyword arguments"
|
50
|
+
end
|
51
|
+
@behavior = behavior
|
52
|
+
@query_parameter_keys = behavior_params[2..-1].map(&:last)
|
53
|
+
end
|
53
54
|
|
54
|
-
|
55
|
+
attr_reader :identifier
|
56
|
+
attr_reader :query_parameter_keys
|
57
|
+
attr_reader :humanized_operator_name
|
55
58
|
|
56
|
-
|
59
|
+
def behavior(&block)
|
60
|
+
self.behavior = block if block_given?
|
61
|
+
@behavior
|
62
|
+
end
|
57
63
|
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
end
|
64
|
+
define("eq", "Equals") do |relation, field, q:|
|
65
|
+
relation.where(field => q)
|
62
66
|
end
|
63
67
|
|
64
|
-
define("
|
65
|
-
relation.where(field =>
|
68
|
+
define("neq", "Doesn't equal") do |relation, field, q:|
|
69
|
+
relation.where.not(field => q)
|
66
70
|
end
|
67
71
|
|
68
|
-
define("
|
69
|
-
relation.where
|
72
|
+
define("null", "Is NULL") do |relation, field|
|
73
|
+
relation.where(field => nil)
|
70
74
|
end
|
71
75
|
|
72
|
-
define("
|
73
|
-
|
74
|
-
relation.where("#{field} LIKE ?", "%#{query}%")
|
76
|
+
define("nnull", "Isn't NULL") do |relation, field|
|
77
|
+
relation.where.not(field => nil)
|
75
78
|
end
|
76
79
|
|
77
|
-
define("
|
78
|
-
|
79
|
-
|
80
|
+
define("true", "Is true") do |relation, field|
|
81
|
+
relation.where(field => true)
|
82
|
+
end
|
83
|
+
|
84
|
+
define("false", "Is false") do |relation, field|
|
85
|
+
relation.where(field => false)
|
86
|
+
end
|
87
|
+
|
88
|
+
define("empty", "Is empty") do |relation, field|
|
89
|
+
relation.where(field => "")
|
80
90
|
end
|
81
91
|
|
82
|
-
define("
|
83
|
-
|
84
|
-
relation.where("#{field} LIKE ?", query)
|
92
|
+
define("nempty", "Isn't empty") do |relation, field|
|
93
|
+
relation.where.not(field => "")
|
85
94
|
end
|
86
95
|
|
87
|
-
define("
|
88
|
-
|
89
|
-
|
96
|
+
define("blank", "Is blank") do |relation, field|
|
97
|
+
relation.where(field => [nil, ""])
|
98
|
+
end
|
99
|
+
|
100
|
+
define("nblank", "Isn't blank") do |relation, field|
|
101
|
+
relation.where.not(field => [nil, ""])
|
102
|
+
end
|
103
|
+
|
104
|
+
define("contain", "Contains") do |relation, field, q:|
|
105
|
+
query = "%#{Compatability.sanitize_sql_like(q)}%"
|
106
|
+
if relation.connection.adapter_name == "PostgreSQL"
|
107
|
+
relation.where("#{field} ILIKE ?", query)
|
108
|
+
else
|
109
|
+
relation.where("#{field} LIKE ?", query)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
define("ncontain", "Doesn't contain") do |relation, field, q:|
|
114
|
+
query = "%#{Compatability.sanitize_sql_like(q)}%"
|
115
|
+
relation.where("#{field} NOT LIKE ?", query)
|
90
116
|
end
|
91
117
|
|
92
|
-
define("between", "
|
93
|
-
if
|
94
|
-
relation = relation.where("#{field} >= ?",
|
118
|
+
define("between", "Between") do |relation, field, q0:, q1:|
|
119
|
+
if q0.present?
|
120
|
+
relation = relation.where("#{field} >= ?", q0)
|
95
121
|
end
|
96
122
|
|
97
|
-
if
|
98
|
-
relation = relation.where("#{field} <= ?",
|
123
|
+
if q1.present?
|
124
|
+
relation = relation.where("#{field} <= ?", q1)
|
99
125
|
end
|
100
126
|
|
101
127
|
relation
|