meta_where 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/.gitmodules +6 -0
- data/CHANGELOG +25 -0
- data/Gemfile +8 -0
- data/LICENSE +20 -0
- data/README.rdoc +274 -0
- data/Rakefile +68 -0
- data/VERSION +1 -0
- data/lib/core_ext/hash.rb +17 -0
- data/lib/core_ext/symbol.rb +31 -0
- data/lib/core_ext/symbol_operators.rb +44 -0
- data/lib/meta_where/builder.rb +84 -0
- data/lib/meta_where/column.rb +53 -0
- data/lib/meta_where/compound.rb +30 -0
- data/lib/meta_where/condition.rb +51 -0
- data/lib/meta_where/join_dependency.rb +48 -0
- data/lib/meta_where/relation.rb +270 -0
- data/lib/meta_where/utility.rb +27 -0
- data/lib/meta_where.rb +27 -0
- data/meta_where.gemspec +105 -0
- data/test/fixtures/companies.yml +17 -0
- data/test/fixtures/company.rb +7 -0
- data/test/fixtures/data_type.rb +3 -0
- data/test/fixtures/data_types.yml +15 -0
- data/test/fixtures/developer.rb +5 -0
- data/test/fixtures/developers.yml +55 -0
- data/test/fixtures/developers_projects.yml +25 -0
- data/test/fixtures/note.rb +3 -0
- data/test/fixtures/notes.yml +79 -0
- data/test/fixtures/people.yml +14 -0
- data/test/fixtures/person.rb +4 -0
- data/test/fixtures/project.rb +4 -0
- data/test/fixtures/projects.yml +24 -0
- data/test/fixtures/schema.rb +52 -0
- data/test/helper.rb +33 -0
- data/test/test_relations.rb +225 -0
- metadata +169 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
module MetaWhere
|
2
|
+
class Compound
|
3
|
+
attr_reader :condition1, :condition2
|
4
|
+
|
5
|
+
def initialize(condition1, condition2)
|
6
|
+
@condition1 = condition1
|
7
|
+
@condition2 = condition2
|
8
|
+
end
|
9
|
+
|
10
|
+
def |(other)
|
11
|
+
Or.new(self, other)
|
12
|
+
end
|
13
|
+
|
14
|
+
def &(other)
|
15
|
+
And.new(self, other)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Or < Compound
|
20
|
+
def to_predicate(builder, parent = nil)
|
21
|
+
condition1.to_predicate(builder, parent).or(condition2.to_predicate(builder, parent))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class And < Compound
|
26
|
+
def to_predicate(builder, parent = nil)
|
27
|
+
condition1.to_predicate(builder, parent).and(condition2.to_predicate(builder, parent))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'meta_where/utility'
|
2
|
+
|
3
|
+
module MetaWhere
|
4
|
+
class Condition
|
5
|
+
include MetaWhere::Utility
|
6
|
+
|
7
|
+
attr_reader :column, :value, :method
|
8
|
+
|
9
|
+
def initialize(column, value, method)
|
10
|
+
@column = column.to_s
|
11
|
+
@value = value
|
12
|
+
@method = (MetaWhere::METHOD_ALIASES[method.to_s] || method).to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_predicate(builder, parent = nil)
|
16
|
+
table = builder.build_table(parent)
|
17
|
+
|
18
|
+
unless attribute = table[column]
|
19
|
+
raise ::ActiveRecord::StatementInvalid, "No attribute named `#{column}` exists for table `#{table.name}`"
|
20
|
+
end
|
21
|
+
|
22
|
+
unless valid_comparison_method?(method)
|
23
|
+
raise ::ActiveRecord::StatementInvalid, "No comparison method named `#{method}` exists for column `#{column}`"
|
24
|
+
end
|
25
|
+
attribute.send(method, *args_for_predicate(method.to_s, value))
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(other_condition)
|
29
|
+
other_condition.is_a?(Condition) &&
|
30
|
+
other_condition.column == column &&
|
31
|
+
other_condition.value = value &&
|
32
|
+
other_condition.method == method
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :eql?, :==
|
36
|
+
|
37
|
+
def |(other)
|
38
|
+
Or.new(self, other)
|
39
|
+
end
|
40
|
+
|
41
|
+
def &(other)
|
42
|
+
And.new(self, other)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Play "nicely" with expand_hash_conditions_for_aggregates
|
46
|
+
def to_sym
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module MetaWhere
|
2
|
+
module JoinDependency
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
alias_method_chain :build, :metawhere
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class BaseMismatchError < StandardError; end
|
11
|
+
class ConfigurationError < StandardError; end
|
12
|
+
class AssociationNotFoundError < StandardError; end
|
13
|
+
|
14
|
+
def build_with_metawhere(associations, parent = nil, join_class = Arel::InnerJoin)
|
15
|
+
parent ||= @joins.last
|
16
|
+
case associations
|
17
|
+
when Symbol, String
|
18
|
+
reflection = parent.reflections[associations.to_s.intern] or
|
19
|
+
raise AssociationNotFoundError, "Association named '#{ associations }' was not found; perhaps you misspelled it?"
|
20
|
+
unless association = find_join_association(reflection, parent)
|
21
|
+
@reflections << reflection
|
22
|
+
association = (@joins << build_join_association(reflection, parent).with_join_class(join_class)).last
|
23
|
+
end
|
24
|
+
association
|
25
|
+
when Array
|
26
|
+
associations.each do |association|
|
27
|
+
build(association, parent, join_class)
|
28
|
+
end
|
29
|
+
when Hash
|
30
|
+
associations.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |name|
|
31
|
+
association = build(name, parent, join_class)
|
32
|
+
build(associations[name], association, join_class)
|
33
|
+
end
|
34
|
+
else
|
35
|
+
raise ConfigurationError, associations.inspect
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def find_join_association(name_or_reflection, parent)
|
40
|
+
case name_or_reflection
|
41
|
+
when Symbol, String
|
42
|
+
join_associations.detect {|j| (j.reflection.name == name_or_reflection.to_s.intern) && (j.parent == parent)}
|
43
|
+
else
|
44
|
+
join_associations.detect {|j| (j.reflection == name_or_reflection) && (j.parent == parent)}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
module MetaWhere
|
2
|
+
module Relation
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
alias_method_chain :reset, :metawhere
|
7
|
+
alias_method_chain :scope_for_create, :metawhere
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def merge(r, association_name = nil)
|
12
|
+
if (r && (association_name || klass.name != r.klass.name)) # Merging relations with different base.
|
13
|
+
association_name ||= (default_association = reflect_on_all_associations.detect {|a| a.klass.name == r.klass.name}) ?
|
14
|
+
default_association.name : r.table_name.to_sym
|
15
|
+
r = r.clone
|
16
|
+
r.where_values.map! {|w| w.respond_to?(:to_predicate) ? {association_name => w} : w}
|
17
|
+
r.joins_values.map! {|j| [Symbol, Hash].include?(j.class) ? {association_name => j} : j}
|
18
|
+
self.joins_values += [association_name]
|
19
|
+
end
|
20
|
+
super(r)
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :&, :merge
|
24
|
+
|
25
|
+
def reset_with_metawhere
|
26
|
+
@mw_unique_joins = @mw_association_joins = @mw_non_association_joins =
|
27
|
+
@mw_stashed_association_joins = @mw_custom_joins = nil
|
28
|
+
reset_without_metawhere
|
29
|
+
end
|
30
|
+
|
31
|
+
def scope_for_create_with_metawhere
|
32
|
+
@scope_for_create ||= begin
|
33
|
+
@create_with_value || predicate_wheres.inject({}) do |hash, where|
|
34
|
+
if is_equality_predicate?(where)
|
35
|
+
hash[where.operand1.name] = where.operand2.respond_to?(:value) ? where.operand2.value : where.operand2
|
36
|
+
end
|
37
|
+
|
38
|
+
hash
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_where(opts, other = [])
|
44
|
+
if opts.is_a?(String)
|
45
|
+
@klass.send(:sanitize_sql, other.empty? ? opts : ([opts] + other))
|
46
|
+
else
|
47
|
+
predicates = []
|
48
|
+
[opts, *other].each do |arg|
|
49
|
+
predicates += Array.wrap(
|
50
|
+
case arg
|
51
|
+
when Array
|
52
|
+
@klass.send(:sanitize_sql, arg)
|
53
|
+
when Hash
|
54
|
+
@klass.send(:expand_hash_conditions_for_aggregates, arg)
|
55
|
+
else
|
56
|
+
arg
|
57
|
+
end
|
58
|
+
)
|
59
|
+
end
|
60
|
+
predicates
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def build_custom_joins(joins = [], arel = nil)
|
65
|
+
arel ||= table
|
66
|
+
joins.each do |join|
|
67
|
+
next if join.blank?
|
68
|
+
|
69
|
+
@implicit_readonly = true
|
70
|
+
|
71
|
+
case join
|
72
|
+
when ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation
|
73
|
+
arel = arel.join(join.relation, Arel::OuterJoin).on(*join.on)
|
74
|
+
when Hash, Array, Symbol
|
75
|
+
if array_of_strings?(join)
|
76
|
+
join_string = join.join(' ')
|
77
|
+
arel = arel.join(join_string)
|
78
|
+
end
|
79
|
+
else
|
80
|
+
arel = arel.join(join)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
arel
|
85
|
+
end
|
86
|
+
|
87
|
+
def custom_join_sql(*joins)
|
88
|
+
arel = table
|
89
|
+
joins.each do |join|
|
90
|
+
next if join.blank?
|
91
|
+
|
92
|
+
@implicit_readonly = true
|
93
|
+
|
94
|
+
case join
|
95
|
+
when Hash, Array, Symbol
|
96
|
+
if array_of_strings?(join)
|
97
|
+
join_string = join.join(' ')
|
98
|
+
arel = arel.join(join_string)
|
99
|
+
end
|
100
|
+
else
|
101
|
+
arel = arel.join(join)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
arel.joins(arel)
|
105
|
+
end unless defined?(:custom_join_sql)
|
106
|
+
|
107
|
+
def predicate_wheres
|
108
|
+
remove_conflicting_equality_predicates(flatten_predicates(@where_values, metawhere_builder))
|
109
|
+
end
|
110
|
+
|
111
|
+
# Very occasionally, we need to get a builder for another relation, so it makes sense to factor
|
112
|
+
# this out into a public method despite only being two lines long.
|
113
|
+
def metawhere_builder
|
114
|
+
join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)
|
115
|
+
MetaWhere::Builder.new(join_dependency)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Simulate the logic that occurs in ActiveRecord::Relation.to_a
|
119
|
+
#
|
120
|
+
# @records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel.to_sql)
|
121
|
+
#
|
122
|
+
# This will let us get a dump of the SQL that will be run against the DB for debug
|
123
|
+
# purposes without actually running the query.
|
124
|
+
def debug_sql
|
125
|
+
if eager_loading?
|
126
|
+
including = (@eager_load_values + @includes_values).uniq
|
127
|
+
join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, including, nil)
|
128
|
+
construct_relation_for_association_find(join_dependency).to_sql
|
129
|
+
else
|
130
|
+
arel.to_sql
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def construct_limited_ids_condition(relation)
|
135
|
+
builder = relation.metawhere_builder
|
136
|
+
|
137
|
+
relation.order_values.map! {|o| o.respond_to?(:to_attribute) ? o.to_attribute(builder).to_sql : o}
|
138
|
+
|
139
|
+
super
|
140
|
+
end
|
141
|
+
|
142
|
+
def build_arel
|
143
|
+
arel = table
|
144
|
+
|
145
|
+
builder = metawhere_builder
|
146
|
+
|
147
|
+
arel = build_intelligent_joins(arel, builder) if @joins_values.present?
|
148
|
+
|
149
|
+
predicate_wheres = remove_conflicting_equality_predicates(flatten_predicates(@where_values, builder))
|
150
|
+
|
151
|
+
predicate_wheres.each do |where|
|
152
|
+
next if where.blank?
|
153
|
+
|
154
|
+
case where
|
155
|
+
when Arel::SqlLiteral
|
156
|
+
arel = arel.where(where)
|
157
|
+
else
|
158
|
+
sql = where.is_a?(String) ? where : where.to_sql
|
159
|
+
arel = arel.where(Arel::SqlLiteral.new("(#{sql})"))
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
arel = arel.having(*@having_values.uniq.select{|h| h.present?}) if @having_values.present?
|
164
|
+
|
165
|
+
arel = arel.take(@limit_value) if @limit_value.present?
|
166
|
+
arel = arel.skip(@offset_value) if @offset_value.present?
|
167
|
+
|
168
|
+
arel = arel.group(*@group_values.uniq.select{|g| g.present?}) if @group_values.present?
|
169
|
+
|
170
|
+
arel = build_order(arel, builder, @order_values) if @order_values.present?
|
171
|
+
|
172
|
+
arel = build_select(arel, @select_values.uniq)
|
173
|
+
|
174
|
+
arel = arel.from(@from_value) if @from_value.present?
|
175
|
+
|
176
|
+
case @lock_value
|
177
|
+
when TrueClass
|
178
|
+
arel = arel.lock
|
179
|
+
when String
|
180
|
+
arel = arel.lock(@lock_value)
|
181
|
+
end if @lock_value.present?
|
182
|
+
|
183
|
+
arel
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
def is_equality_predicate?(predicate)
|
189
|
+
predicate.respond_to?(:operator) && predicate.operator == :==
|
190
|
+
end
|
191
|
+
|
192
|
+
def build_intelligent_joins(arel, builder)
|
193
|
+
joined_associations = []
|
194
|
+
|
195
|
+
builder.join_dependency.graft(*stashed_association_joins)
|
196
|
+
|
197
|
+
@implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?
|
198
|
+
|
199
|
+
to_join = []
|
200
|
+
|
201
|
+
builder.join_dependency.join_associations.each do |association|
|
202
|
+
if (association_relation = association.relation).is_a?(Array)
|
203
|
+
to_join << [association_relation.first, association.join_class, association.association_join.first]
|
204
|
+
to_join << [association_relation.last, association.join_class, association.association_join.last]
|
205
|
+
else
|
206
|
+
to_join << [association_relation, association.join_class, association.association_join]
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
to_join.each do |tj|
|
211
|
+
unless joined_associations.detect {|ja| ja[0] == tj[0] && ja[1] == tj[1] && ja[2] == tj[2] }
|
212
|
+
joined_associations << tj
|
213
|
+
arel = arel.join(tj[0], tj[1]).on(*tj[2])
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
arel = arel.join(custom_joins)
|
218
|
+
end
|
219
|
+
|
220
|
+
def build_order(arel, builder, orders)
|
221
|
+
order_attributes = orders.map {|o|
|
222
|
+
o.respond_to?(:to_attribute) ? o.to_attribute(builder, builder.join_dependency.join_base) : o
|
223
|
+
}.flatten.uniq.select {|o| o.present?}
|
224
|
+
order_attributes.map! {|a| Arel::SqlLiteral.new(a.is_a?(String) ? a : a.to_sql)}
|
225
|
+
order_attributes.present? ? arel.order(*order_attributes) : arel
|
226
|
+
end
|
227
|
+
|
228
|
+
def remove_conflicting_equality_predicates(predicates)
|
229
|
+
predicates.reverse.inject([]) { |ary, w|
|
230
|
+
unless is_equality_predicate?(w) && ary.any? {|p| is_equality_predicate?(p) && p.operand1.name == w.operand1.name}
|
231
|
+
ary << w
|
232
|
+
end
|
233
|
+
ary
|
234
|
+
}.reverse
|
235
|
+
end
|
236
|
+
|
237
|
+
def flatten_predicates(predicates, builder)
|
238
|
+
predicates.map {|p|
|
239
|
+
predicate = p.respond_to?(:to_predicate) ? p.to_predicate(builder) : p
|
240
|
+
if predicate.is_a?(Arel::Predicates::All)
|
241
|
+
flatten_predicates(predicate.predicates, builder)
|
242
|
+
else
|
243
|
+
predicate
|
244
|
+
end
|
245
|
+
}.flatten.uniq
|
246
|
+
end
|
247
|
+
|
248
|
+
def unique_joins
|
249
|
+
@mw_unique_joins ||= @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
|
250
|
+
end
|
251
|
+
|
252
|
+
def association_joins
|
253
|
+
@mw_association_joins ||= unique_joins.select{|j|
|
254
|
+
[Hash, Array, Symbol].include?(j.class) && !array_of_strings?(j)
|
255
|
+
}
|
256
|
+
end
|
257
|
+
|
258
|
+
def stashed_association_joins
|
259
|
+
@mw_stashed_association_joins ||= unique_joins.select {|j| j.is_a?(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)}
|
260
|
+
end
|
261
|
+
|
262
|
+
def non_association_joins
|
263
|
+
@mw_non_association_joins ||= (unique_joins - association_joins - stashed_association_joins).reject {|j| j.blank?}
|
264
|
+
end
|
265
|
+
|
266
|
+
def custom_joins
|
267
|
+
@mw_custom_joins ||= custom_join_sql(*non_association_joins)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MetaWhere
|
2
|
+
module Utility
|
3
|
+
private
|
4
|
+
|
5
|
+
def args_for_predicate(method, value)
|
6
|
+
value = [Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation].include?(value.class) ? value.to_a : value
|
7
|
+
if method =~ /_(any|all)$/ && value.is_a?(Array)
|
8
|
+
value
|
9
|
+
else
|
10
|
+
[value]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_from_value(value)
|
15
|
+
case value
|
16
|
+
when Array, Range, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation
|
17
|
+
:in
|
18
|
+
else
|
19
|
+
:eq
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_comparison_method?(method)
|
24
|
+
Arel::Attribute::PREDICATES.map(&:to_s).include?(method.to_s)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/meta_where.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module MetaWhere
|
2
|
+
METHOD_ALIASES = {
|
3
|
+
'ne' => :not_eq,
|
4
|
+
'like' => :matches,
|
5
|
+
'nlike' => :not_matches,
|
6
|
+
'lte' => :lteq,
|
7
|
+
'gte' => :gteq,
|
8
|
+
'nin' => :not_in
|
9
|
+
}
|
10
|
+
|
11
|
+
def self.operator_overload!
|
12
|
+
require 'core_ext/symbol_operators'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
require 'arel'
|
16
|
+
require 'active_record'
|
17
|
+
require 'active_support'
|
18
|
+
require 'meta_where/column'
|
19
|
+
require 'meta_where/condition'
|
20
|
+
require 'meta_where/compound'
|
21
|
+
require 'core_ext/symbol'
|
22
|
+
require 'core_ext/hash'
|
23
|
+
require 'meta_where/builder'
|
24
|
+
require 'meta_where/relation'
|
25
|
+
require 'meta_where/join_dependency'
|
26
|
+
ActiveRecord::Relation.send(:include, MetaWhere::Relation)
|
27
|
+
ActiveRecord::Associations::ClassMethods::JoinDependency.send(:include, MetaWhere::JoinDependency)
|
data/meta_where.gemspec
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{meta_where}
|
8
|
+
s.version = "0.9.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Ernie Miller"]
|
12
|
+
s.date = %q{2010-08-24}
|
13
|
+
s.description = %q{
|
14
|
+
MetaWhere offers the ability to call any Arel predicate methods
|
15
|
+
(with a few convenient aliases) on your Model's attributes instead
|
16
|
+
of the ones normally offered by ActiveRecord's hash parameters. It also
|
17
|
+
adds convenient syntax for order clauses, smarter mapping of nested hash
|
18
|
+
conditions, and a debug_sql method to see the real SQL your code is
|
19
|
+
generating without running it against the database. If you like the new
|
20
|
+
AR 3.0 query interface, you'll love it with MetaWhere.
|
21
|
+
}
|
22
|
+
s.email = %q{ernie@metautonomo.us}
|
23
|
+
s.extra_rdoc_files = [
|
24
|
+
"LICENSE",
|
25
|
+
"README.rdoc"
|
26
|
+
]
|
27
|
+
s.files = [
|
28
|
+
".document",
|
29
|
+
".gitignore",
|
30
|
+
".gitmodules",
|
31
|
+
"CHANGELOG",
|
32
|
+
"Gemfile",
|
33
|
+
"LICENSE",
|
34
|
+
"README.rdoc",
|
35
|
+
"Rakefile",
|
36
|
+
"VERSION",
|
37
|
+
"lib/core_ext/hash.rb",
|
38
|
+
"lib/core_ext/symbol.rb",
|
39
|
+
"lib/core_ext/symbol_operators.rb",
|
40
|
+
"lib/meta_where.rb",
|
41
|
+
"lib/meta_where/builder.rb",
|
42
|
+
"lib/meta_where/column.rb",
|
43
|
+
"lib/meta_where/compound.rb",
|
44
|
+
"lib/meta_where/condition.rb",
|
45
|
+
"lib/meta_where/join_dependency.rb",
|
46
|
+
"lib/meta_where/relation.rb",
|
47
|
+
"lib/meta_where/utility.rb",
|
48
|
+
"meta_where.gemspec",
|
49
|
+
"test/fixtures/companies.yml",
|
50
|
+
"test/fixtures/company.rb",
|
51
|
+
"test/fixtures/data_type.rb",
|
52
|
+
"test/fixtures/data_types.yml",
|
53
|
+
"test/fixtures/developer.rb",
|
54
|
+
"test/fixtures/developers.yml",
|
55
|
+
"test/fixtures/developers_projects.yml",
|
56
|
+
"test/fixtures/note.rb",
|
57
|
+
"test/fixtures/notes.yml",
|
58
|
+
"test/fixtures/people.yml",
|
59
|
+
"test/fixtures/person.rb",
|
60
|
+
"test/fixtures/project.rb",
|
61
|
+
"test/fixtures/projects.yml",
|
62
|
+
"test/fixtures/schema.rb",
|
63
|
+
"test/helper.rb",
|
64
|
+
"test/test_relations.rb"
|
65
|
+
]
|
66
|
+
s.homepage = %q{http://metautonomo.us/projects/metawhere/}
|
67
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
68
|
+
s.require_paths = ["lib"]
|
69
|
+
s.rubygems_version = %q{1.3.7}
|
70
|
+
s.summary = %q{Add a dash of Arel awesomeness to your condition hashes.}
|
71
|
+
s.test_files = [
|
72
|
+
"test/fixtures/company.rb",
|
73
|
+
"test/fixtures/data_type.rb",
|
74
|
+
"test/fixtures/developer.rb",
|
75
|
+
"test/fixtures/note.rb",
|
76
|
+
"test/fixtures/person.rb",
|
77
|
+
"test/fixtures/project.rb",
|
78
|
+
"test/fixtures/schema.rb",
|
79
|
+
"test/helper.rb",
|
80
|
+
"test/test_relations.rb"
|
81
|
+
]
|
82
|
+
|
83
|
+
if s.respond_to? :specification_version then
|
84
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
85
|
+
s.specification_version = 3
|
86
|
+
|
87
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
88
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
89
|
+
s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0.rc2"])
|
90
|
+
s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0.rc2"])
|
91
|
+
s.add_runtime_dependency(%q<arel>, ["~> 1.0.0.rc1"])
|
92
|
+
else
|
93
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
94
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.0.rc2"])
|
95
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.0.rc2"])
|
96
|
+
s.add_dependency(%q<arel>, ["~> 1.0.0.rc1"])
|
97
|
+
end
|
98
|
+
else
|
99
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
100
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.0.rc2"])
|
101
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.0.rc2"])
|
102
|
+
s.add_dependency(%q<arel>, ["~> 1.0.0.rc1"])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
initech:
|
2
|
+
name : Initech
|
3
|
+
id : 1
|
4
|
+
created_at: 1999-02-19 08:00
|
5
|
+
updated_at: 1999-02-19 08:00
|
6
|
+
|
7
|
+
aos:
|
8
|
+
name: Advanced Optical Solutions
|
9
|
+
id : 2
|
10
|
+
created_at: 2004-02-01 08:00
|
11
|
+
updated_at: 2004-02-01 08:00
|
12
|
+
|
13
|
+
mission_data:
|
14
|
+
name: Mission Data
|
15
|
+
id : 3
|
16
|
+
created_at: 1996-09-21 08:00
|
17
|
+
updated_at: 1996-09-21 08:00
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class Company < ActiveRecord::Base
|
2
|
+
has_many :developers
|
3
|
+
has_many :developer_notes, :through => :developers, :source => :notes
|
4
|
+
has_many :slackers, :class_name => "Developer", :conditions => {:slacker => true}
|
5
|
+
has_many :notes, :as => :notable
|
6
|
+
has_many :data_types
|
7
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<% 1.upto(9) do |n| %>
|
2
|
+
dt_<%= n %>:
|
3
|
+
company_id: <%= n % 3 + 1 %>
|
4
|
+
str : This string has <%= n %> exclamation points<%= '!' * n %>
|
5
|
+
txt : <%= 'This is some text that may or may not repeat based on the value of n.' * n %>
|
6
|
+
int : <%= n ** 3 %>
|
7
|
+
flt : <%= n.to_f / 2.0 %>
|
8
|
+
dec : <%= n.to_f ** (n + 0.1) %>
|
9
|
+
dtm : <%= (Time.utc(2009, 12, 24) + 86400 * n).to_s(:db) %>
|
10
|
+
tms : <%= (Time.utc(2009, 12, 24) + 86400 * n).to_s(:db) %>
|
11
|
+
tim : <%= Time.utc(2000, 01, 01, n+8, n).to_s(:db) %>
|
12
|
+
dat : <%= (Date.new(2009, 12, 24) + n).strftime("%Y-%m-%d") %>
|
13
|
+
bin : <%= "BLOB#{n}" * n %>
|
14
|
+
bln : <%= n % 2 > 0 ? true : false %>
|
15
|
+
<% end %>
|
@@ -0,0 +1,55 @@
|
|
1
|
+
peter:
|
2
|
+
id : 1
|
3
|
+
company_id: 1
|
4
|
+
name : Peter Gibbons
|
5
|
+
salary : 100000
|
6
|
+
slacker : true
|
7
|
+
|
8
|
+
michael:
|
9
|
+
id : 2
|
10
|
+
company_id: 1
|
11
|
+
name : Michael Bolton
|
12
|
+
salary : 70000
|
13
|
+
slacker : false
|
14
|
+
|
15
|
+
samir:
|
16
|
+
id : 3
|
17
|
+
company_id: 1
|
18
|
+
name : Samir Nagheenanajar
|
19
|
+
salary : 65000
|
20
|
+
slacker : false
|
21
|
+
|
22
|
+
herb:
|
23
|
+
id : 4
|
24
|
+
company_id: 2
|
25
|
+
name : Herb Myers
|
26
|
+
salary : 50000
|
27
|
+
slacker : false
|
28
|
+
|
29
|
+
dude:
|
30
|
+
id : 5
|
31
|
+
company_id: 2
|
32
|
+
name : Some Dude
|
33
|
+
salary : 84000
|
34
|
+
slacker : true
|
35
|
+
|
36
|
+
ernie:
|
37
|
+
id : 6
|
38
|
+
company_id: 3
|
39
|
+
name : Ernie Miller
|
40
|
+
salary : 45000
|
41
|
+
slacker : true
|
42
|
+
|
43
|
+
someone:
|
44
|
+
id : 7
|
45
|
+
company_id: 3
|
46
|
+
name : Someone Else
|
47
|
+
salary : 70000
|
48
|
+
slacker : true
|
49
|
+
|
50
|
+
another:
|
51
|
+
id : 8
|
52
|
+
company_id: 3
|
53
|
+
name : Another Guy
|
54
|
+
salary : 80000
|
55
|
+
slacker : false
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<% 1.upto(3) do |d| %>
|
2
|
+
y2k_<%= d %>:
|
3
|
+
developer_id: <%= d %>
|
4
|
+
project_id : 1
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
virus:
|
8
|
+
developer_id: 2
|
9
|
+
project_id : 2
|
10
|
+
|
11
|
+
<% 1.upto(8) do |d| %>
|
12
|
+
awesome_<%= d %>:
|
13
|
+
developer_id: <%= d %>
|
14
|
+
project_id : 3
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
metasearch:
|
18
|
+
developer_id: 6
|
19
|
+
project_id : 4
|
20
|
+
|
21
|
+
<% 4.upto(8) do |d| %>
|
22
|
+
another_<%= d %>:
|
23
|
+
developer_id: <%= d %>
|
24
|
+
project_id : 5
|
25
|
+
<% end %>
|