meta_where 0.9.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.
- 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 %>
|