Class: Marty::BaseRule
- Inherits:
-
Base
show all
- Defined in:
- app/models/marty/base_rule.rb
Constant Summary
ActiveRecord::Base::COUNT_SIG, ActiveRecord::Base::DISTINCT_SIG, ActiveRecord::Base::FIND_BY_SIG, ActiveRecord::Base::FIRST_SIG, ActiveRecord::Base::GROUP_SIG, ActiveRecord::Base::JOINS_SIG, ActiveRecord::Base::LAST_SIG, ActiveRecord::Base::LIMIT_SIG, ActiveRecord::Base::MCFLY_PT_SIG, ActiveRecord::Base::NOT_SIG, ActiveRecord::Base::ORDER_SIG, ActiveRecord::Base::PLUCK_SIG, ActiveRecord::Base::SELECT_SIG, ActiveRecord::Base::WHERE_SIG
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Base
get_final_attrs, get_struct_attrs, make_hash, make_openstruct, mcfly_pt
joins, old_joins
Class Method Details
.get_matches_(pt, attrs, params) ⇒ Object
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
# File 'app/models/marty/base_rule.rb', line 93
def self.get_matches_(pt, attrs, params)
q = select("DISTINCT ON (name) *").where(attrs)
params.each do |k, vraw|
h = guard_info
use_k = (h[k] && k) ||
(h[k+"_array"] && k+"_array") ||
(h[k+"_range"] && k+"_range")
next unless use_k
multi, type = h[use_k].values_at(:multi, :type)
filts = [vraw].flatten.map do |v|
qstr = get_subq('simple_guards', use_k, multi, type, v)
end.join(" OR ")
isn = "simple_guards->'#{use_k}' IS NULL OR"
q = q.where("(#{isn} #{filts})")
end
q.order(:name)
end
|
.get_subq(field, subfield, multi, type, vraw) ⇒ Object
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'app/models/marty/base_rule.rb', line 80
def self.get_subq(field, subfield, multi, type, vraw)
arrow = multi || ![:range, :string, :date, :datetime].include?(type) ?
"->" : "->>"
op = multi || type == :range ? "@>" : "="
value0 = [:string, :date, :datetime].include?(type) ?
ActiveRecord::Base.connection.quote(vraw) :
type == :range ? vraw.to_f :
"'#{vraw}'::jsonb"
value = multi ? %Q('["%s"]') % value0[1..-2] : value0
fieldcast = type == :range ? "::numrange" : ''
"(#{field}#{arrow}'#{subfield}')#{fieldcast} #{op} #{value}"
end
|
.guard_info ⇒ Object
5
6
7
|
# File 'app/models/marty/base_rule.rb', line 5
def self.guard_info
{}
end
|
Instance Method Details
#check(name, h) ⇒ Object
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# File 'app/models/marty/base_rule.rb', line 23
def check(name, h)
multi, type, enum, values, req = h.values_at(:multi, :type, :enum, :values,
:required)
ns = "'#{name}'"
expmulti = multi ? 'multi' : 'single'
errtype = :guards
v = simple_guards[name]
type ||= :string
return errors[errtype] << "- Required field #{ns} is missing" if
v.blank? && req
return if v.blank?
gotmulti = v.is_a?(Array) ? 'multi' : 'single'
return errors[errtype] << "- Wrong arity for #{ns} (expected #{expmulti} "\
"got #{gotmulti})" if expmulti != gotmulti
vs = [v].flatten.to_set
vs.each do |vv|
return errors[errtype] << "- Wrong type for #{ns}" unless
gettypes(vv).member?(type)
end
return unless enum || values
vals = enum && enum::VALUES || values.to_set
bad = (vs - vals)
p = bad.count > 1 ? 's' : ''
return errors[errtype] <<
%Q(- Bad value#{p} '#{bad.to_a.join("', '")}' for #{ns}) if bad.present?
end
|
#chkrange(v) ⇒ Object
9
10
11
|
# File 'app/models/marty/base_rule.rb', line 9
def chkrange(v)
v.match(/\A(\[|\()([0-9\.-]*),([0-9\.-]*)(\]|\))\z/)
end
|
#gettypes(v) ⇒ Object
12
13
14
15
16
17
18
19
20
21
22
|
# File 'app/models/marty/base_rule.rb', line 12
def gettypes(v)
types = []
types << :string if v.is_a?(String)
types += [:int, :integer] if Integer(v) rescue nil
types << :float if Float(v) rescue nil
types << :date if Date.parse(v) rescue nil
types << :datetime if DateTime.parse(v) rescue nil
types << :range if chkrange(v) rescue nil
types << :boolean if [true, false, 'True', 'False'].include?(v)
types
end
|
#validate ⇒ Object
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# File 'app/models/marty/base_rule.rb', line 49
def validate
self.class.guard_info.each { |name, h| check(name, h) }
grids.each do |vn, gn|
return errors[:grids] << "- Bad grid name '#{gn}' for '#{vn}'" unless
gn.blank? || Marty::DataGrid.lookup('infinity', gn)
end
cg_err = computed_guards.delete("~~ERROR~~")
errors[:computed] <<
"- Error in rule '#{name}' field 'computed_guards': #{cg_err.capitalize}" if cg_err
res_err = results.delete("~~ERROR~~")
errors[:computed] <<
"- Error in rule '#{name}' field 'results': #{res_err.capitalize}" if res_err
end
|