EZ::Condition plugin for generating the :conditions where clause for ActiveRecord::Base.find. And an extension to ActiveRecord::Base called AR::Base.find_with_conditions that takes a block and builds the where clause dynamically for you.
- <<
- add_sql
- all
- and_condition
- any
- append
- clause
- clone_from
- condition
- define_sub
- method_missing
- new
- or_condition
- sql_condition
- sub
- to_sql
| [R] | clauses | these are also reserved words regarding SQL column names use esc_* prefix to circumvent any issues |
| [RW] | inner | |
| [RW] | outer |
Initialize @clauses and eval the block so it invokes method_missing.
[ show source ]
# File lib/og/ez/condition.rb, line 25
25: def initialize(*args, &block)
26: options = args.last.is_a?(Hash) ? args.last : {}
27: options[:table_name] = args.first if args.first.kind_of? Symbol
28: @table_name = options.delete(:table_name) || nil
29: @outer = options.delete(:outer) || :and
30: @inner = options.delete(:inner) || :and
31: @clauses = []
32: instance_eval(&block) if block_given?
33: end
Append a condition element, which can be one of the following:
[ show source ]
# File lib/og/ez/condition.rb, line 113
113: def <<(condition, outer = nil)
114: if condition.kind_of?(String) and not condition.to_s.empty?
115: cond = SqlClause.new(condition)
116: cond.outer = outer || :and
117: @clauses << cond
118: elsif condition.kind_of?(Og::ModelMixin)
119: if condition.attributes[condition.class.primary_key].nil?
120: condition.attributes.each { |k, v| clause([condition.class.table_name, k]) == v unless v.to_s.empty? }
121: else
122: clause([condition.class.table_name, condition.class.primary_key]) == condition.attributes[condition.class.primary_key]
123: end
124: else
125: if condition.kind_of?(Condition) or condition.kind_of?(AbstractClause)
126: logic = condition.outer if outer.nil?
127: condition = condition.to_sql
128: else
129: logic = outer
130: end
131: if condition.kind_of?(Array) and not condition.empty?
132: array_clause = ArrayClause.new(condition)
133: array_clause.outer = logic
134: @clauses << array_clause
135: end
136: end
137: end
Alias for #and_condition
Shortcut for adding a :and boolean joined subcondition
[ show source ]
# File lib/og/ez/condition.rb, line 85
85: def and_condition(*args, &block)
86: options = args.last.is_a?(Hash) ? args.last : {}
87: options[:table_name] = args.first if args.first.kind_of? Symbol
88: options[:outer] ||= @outer
89: options[:inner] ||= :and
90: define_sub(options, &block)
91: end
Alias for #or_condition
You can define clauses dynamicly using this method. It will take a clause and create the correct Clause object to process the conditions
[ show source ]
# File lib/og/ez/condition.rb, line 56
56: def clause(name, *args)
57: if name.kind_of?(Array)
58: c = Clause.new(name.first, name.last)
59: elsif args.last.kind_of?(Symbol)
60: c = Clause.new(args.pop, name)
61: else
62: c = Clause.new(@table_name, name)
63: end
64: @clauses << c
65: c
66: end
Alias for #define_sub
Create subcondition from a block, optionally specifying table_name, outer and inner. :outer determines how the subcondition is added to the condition, while :inner determines the internal ‘joining’ of conditions inside the subcondition. Both :inner & :outer defult to ‘AND‘
[ show source ]
# File lib/og/ez/condition.rb, line 72
72: def define_sub(*args, &block)
73: options = args.last.is_a?(Hash) ? args.last : {}
74: options[:table_name] = args.first if args.first.kind_of? Symbol
75: options[:table_name] ||= @table_name
76: cond = Condition.new(options, &block)
77: self << cond
78: end
When invoked with the name of the column in each statement inside the block: A new Clause instance is created and recieves the args. Then the operator hits method_missing and gets sent to a new Clause instance where it either matches one of the defined ops or hits method_missing there.
When invoked with an attached block a subcondition is created. The name is regarded as the table_name, additional parameters for outer and inner are passed on.
[ show source ]
# File lib/og/ez/condition.rb, line 43
43: def method_missing(name, *args, &block)
44: if block_given?
45: # handle name as table_name and create a subcondition
46: options = args.last.is_a?(Hash) ? args.last : {}
47: options[:table_name] ||= name
48: define_sub(options, &block)
49: else
50: clause(name, *args)
51: end
52: end
Shortcut for adding a :or boolean joined subcondition
[ show source ]
# File lib/og/ez/condition.rb, line 97
97: def or_condition(*args, &block)
98: options = args.last.is_a?(Hash) ? args.last : {}
99: options[:table_name] = args.first if args.first.kind_of? Symbol
100: options[:outer] ||= @outer
101: options[:inner] ||= :or
102: define_sub(options, &block)
103: end
Alias for #define_sub
Loop over all Clause onjects in @clauses array and call to_sql on each instance. Then join the queries and params into the :conditions array with logic defaulting to AND. Subqueries are joined together using their individual outer property setting if present. Also defaults to AND.
[ show source ]
# File lib/og/ez/condition.rb, line 154
154: def to_sql(logic=@inner)
155: params = []; query = []
156: @clauses.each do |cv|
157: q, p, e = cv.to_sql
158: unless q.to_s.empty?
159: logic = cv.outer ? cv.outer : logic
160: logic = logic.to_s.upcase
161: logic = 'AND NOT' if logic == 'NOT'
162: query << logic unless query.empty?
163: query << q
164: if cv.test == :in
165: params << p if p.respond_to?(:map)
166: elsif p.kind_of?(Array)
167: p.flatten! unless q =~ /IN/
168: params += p
169: else
170: params << p unless p.nil?
171: params << e unless e.nil?
172: end
173: end
174: end
175: [query.join(' '), *params ]
176: end