squeel 1.0.6 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +4 -0
- data/lib/squeel/adapters/active_record.rb +1 -1
- data/lib/squeel/adapters/active_record/3.0/relation_extensions.rb +7 -3
- data/lib/squeel/adapters/active_record/3.1/relation_extensions.rb +82 -17
- data/lib/squeel/adapters/active_record/base_extensions.rb +20 -1
- data/lib/squeel/adapters/active_record/relation_extensions.rb +2 -3
- data/lib/squeel/nodes/function.rb +1 -12
- data/lib/squeel/nodes/operation.rb +1 -1
- data/lib/squeel/version.rb +1 -1
- data/lib/squeel/visitors/attribute_visitor.rb +3 -3
- data/lib/squeel/visitors/predicate_visitor.rb +3 -3
- data/spec/squeel/adapters/active_record/relation_extensions_spec.rb +55 -13
- data/spec/squeel/nodes/function_spec.rb +0 -14
- data/spec/squeel/nodes/operation_spec.rb +0 -14
- data/spec/support/schema.rb +2 -1
- metadata +4 -4
data/CHANGELOG.md
CHANGED
@@ -20,7 +20,7 @@ when 3
|
|
20
20
|
require 'squeel/adapters/active_record/3.1/relation_extensions'
|
21
21
|
require 'squeel/adapters/active_record/3.1/preloader_extensions'
|
22
22
|
require 'squeel/adapters/active_record/3.1/context'
|
23
|
-
|
23
|
+
|
24
24
|
ActiveRecord::Relation.send :include, Squeel::Adapters::ActiveRecord::RelationExtensions
|
25
25
|
ActiveRecord::Associations::JoinDependency.send :include, Squeel::Adapters::ActiveRecord::JoinDependencyExtensions
|
26
26
|
ActiveRecord::Associations::Preloader.send :include, Squeel::Adapters::ActiveRecord::PreloaderExtensions
|
@@ -39,14 +39,18 @@ module Squeel
|
|
39
39
|
# behavior with Squeel loaded is to visit the *_values arrays in
|
40
40
|
# the relations we're merging, and then use the default AR merge
|
41
41
|
# code on the result.
|
42
|
-
def merge(r,
|
43
|
-
if
|
42
|
+
def merge(r, skip_visit = false)
|
43
|
+
if skip_visit or not ::ActiveRecord::Relation === r
|
44
44
|
super(r)
|
45
45
|
else
|
46
|
-
|
46
|
+
visited.merge(r.visited, true)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
def visited
|
51
|
+
clone.visit!
|
52
|
+
end
|
53
|
+
|
50
54
|
def visit!
|
51
55
|
predicate_viz = predicate_visitor
|
52
56
|
attribute_viz = attribute_visitor
|
@@ -39,22 +39,16 @@ module Squeel
|
|
39
39
|
# behavior with Squeel loaded is to visit the *_values arrays in
|
40
40
|
# the relations we're merging, and then use the default AR merge
|
41
41
|
# code on the result.
|
42
|
-
def merge(r,
|
43
|
-
if
|
42
|
+
def merge(r, skip_visit = false)
|
43
|
+
if skip_visit or not ::ActiveRecord::Relation === r
|
44
44
|
super(r)
|
45
45
|
else
|
46
|
-
|
46
|
+
visited.merge(r.visited, true)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def
|
51
|
-
|
52
|
-
r.having_values.map! {|h| Squeel::Visitors::PredicateVisitor.can_visit?(h) ? {association_name => h} : h}
|
53
|
-
r.group_values.map! {|g| Squeel::Visitors::AttributeVisitor.can_visit?(g) ? {association_name => g} : g}
|
54
|
-
r.order_values.map! {|o| Squeel::Visitors::AttributeVisitor.can_visit?(o) ? {association_name => o} : o}
|
55
|
-
r.select_values.map! {|s| Squeel::Visitors::AttributeVisitor.can_visit?(s) ? {association_name => s} : s}
|
56
|
-
r.joins_values.map! {|j| [Symbol, Hash, Nodes::Stub, Nodes::Join, Nodes::KeyPath].include?(j.class) ? {association_name => j} : j}
|
57
|
-
r.includes_values.map! {|i| [Symbol, Hash, Nodes::Stub, Nodes::Join, Nodes::KeyPath].include?(i.class) ? {association_name => i} : i}
|
50
|
+
def visited
|
51
|
+
clone.visit!
|
58
52
|
end
|
59
53
|
|
60
54
|
def visit!
|
@@ -89,9 +83,9 @@ module Squeel
|
|
89
83
|
arel.group(*attribute_viz.accept(@group_values.uniq.reject{|g| g.blank?})) unless @group_values.empty?
|
90
84
|
|
91
85
|
order = @reorder_value ? @reorder_value : @order_values
|
92
|
-
order = attribute_viz.accept(order
|
86
|
+
order = attribute_viz.accept(order)
|
93
87
|
order = reverse_sql_order(attrs_to_orderings(order)) if @reverse_order_value
|
94
|
-
arel.order(*order) unless order.empty?
|
88
|
+
arel.order(*order.uniq.reject{|o| o.blank?}) unless order.empty?
|
95
89
|
|
96
90
|
build_select(arel, attribute_viz.accept(@select_values.uniq))
|
97
91
|
|
@@ -318,6 +312,33 @@ module Squeel
|
|
318
312
|
}.compact.flatten
|
319
313
|
end
|
320
314
|
|
315
|
+
def flatten_nodes(nodes)
|
316
|
+
nodes.map { |node|
|
317
|
+
case node
|
318
|
+
when Array
|
319
|
+
flatten_nodes(node)
|
320
|
+
when Nodes::And
|
321
|
+
flatten_nodes(node.children)
|
322
|
+
when Nodes::Grouping
|
323
|
+
flatten_nodes(node.expr)
|
324
|
+
else
|
325
|
+
node
|
326
|
+
end
|
327
|
+
}.flatten
|
328
|
+
end
|
329
|
+
|
330
|
+
def overwrite_squeel_equalities(wheres)
|
331
|
+
seen = {}
|
332
|
+
flatten_nodes(wheres).reverse.reject { |n|
|
333
|
+
nuke = false
|
334
|
+
if Nodes::Predicate === n && n.method_name == :eq
|
335
|
+
nuke = seen[n.expr]
|
336
|
+
seen[n.expr] = true
|
337
|
+
end
|
338
|
+
nuke
|
339
|
+
}.reverse
|
340
|
+
end
|
341
|
+
|
321
342
|
# Simulate the logic that occurs in #to_a
|
322
343
|
#
|
323
344
|
# This will let us get a dump of the SQL that will be run against the
|
@@ -338,9 +359,11 @@ module Squeel
|
|
338
359
|
# ...
|
339
360
|
# Since you're still looking, let me explain this horrible
|
340
361
|
# transgression you see before you.
|
341
|
-
#
|
342
|
-
#
|
343
|
-
#
|
362
|
+
#
|
363
|
+
# You see, Relation#where_values_hash and with_default_scope
|
364
|
+
# are defined on the ActiveRecord::Relation class, itself.
|
365
|
+
# ActiveRecord::Relation class. Since they're defined there, but
|
366
|
+
# I would very much like to modify their behavior, I have three
|
344
367
|
# choices.
|
345
368
|
#
|
346
369
|
# 1. Inherit from ActiveRecord::Relation in a Squeel::Relation
|
@@ -349,7 +372,7 @@ module Squeel
|
|
349
372
|
# evil stuff with constant reassignment, all for the sake of
|
350
373
|
# being able to use super().
|
351
374
|
#
|
352
|
-
# 2. Submit a patch to Rails core, breaking
|
375
|
+
# 2. Submit a patch to Rails core, breaking these methods off into
|
353
376
|
# another module, all for my own selfish desire to use super()
|
354
377
|
# while mucking about in Rails internals.
|
355
378
|
#
|
@@ -357,19 +380,61 @@ module Squeel
|
|
357
380
|
#
|
358
381
|
# I opted to go with #3. Except for the hail Hansson thing.
|
359
382
|
# Unless you're DHH, in which case, I totally said them.
|
383
|
+
#
|
384
|
+
# If you'd like to read more about alias_method_chain, see
|
385
|
+
# http://erniemiller.org/2011/02/03/when-to-use-alias_method_chain/
|
360
386
|
|
361
387
|
def self.included(base)
|
362
388
|
base.class_eval do
|
363
389
|
alias_method_chain :where_values_hash, :squeel
|
390
|
+
alias_method_chain :with_default_scope, :squeel
|
364
391
|
end
|
365
392
|
end
|
366
393
|
|
394
|
+
# where_values_hash is used in scope_for_create. It's what allows
|
395
|
+
# new records to be created with any equality values that exist in
|
396
|
+
# your model's default scope. We hijack it in order to dig down into
|
397
|
+
# And and Grouping nodes, which are equivalent to seeing top-level
|
398
|
+
# Equality nodes in stock AR terms.
|
367
399
|
def where_values_hash_with_squeel
|
368
400
|
equalities = find_equality_predicates(predicate_visitor.accept(with_default_scope.where_values))
|
369
401
|
|
370
402
|
Hash[equalities.map { |where| [where.left.name, where.right] }]
|
371
403
|
end
|
372
404
|
|
405
|
+
# with_default_scope was added to ActiveRecord ~> 3.1 in order to
|
406
|
+
# address https://github.com/rails/rails/issues/1233. Unfortunately,
|
407
|
+
# it plays havoc with Squeel's approach of visiting both sides of
|
408
|
+
# a relation merge. Thankfully, when merging with a relation from
|
409
|
+
# the same AR::Base, it's unnecessary to visit...
|
410
|
+
#
|
411
|
+
# Except, of course, this means we have to handle the edge case
|
412
|
+
# where equalities are duplicated on both sides of the merge, in
|
413
|
+
# which case, unlike all other chained relation calls, the latter
|
414
|
+
# equality overwrites the former.
|
415
|
+
#
|
416
|
+
# The workaround using overwrite_squeel_equalities works as long
|
417
|
+
# as you stick to the Squeel DSL, but breaks down if you throw hash
|
418
|
+
# conditions into the mix. If anyone's got any suggestions, I'm all
|
419
|
+
# ears. Otherwise, just stick to the Squeel DSL.
|
420
|
+
#
|
421
|
+
# Or, don't use default scopes. They're the devil, anyway. I can't
|
422
|
+
# remember the last time I used one and didn't find myself
|
423
|
+
# regretting the decision later.
|
424
|
+
def with_default_scope_with_squeel
|
425
|
+
if default_scoped? &&
|
426
|
+
default_scope = klass.build_default_scope_with_squeel
|
427
|
+
default_scope = default_scope.merge(self, true)
|
428
|
+
default_scope.default_scoped = false
|
429
|
+
default_scope.where_values = overwrite_squeel_equalities(
|
430
|
+
default_scope.where_values + self.where_values
|
431
|
+
)
|
432
|
+
default_scope
|
433
|
+
else
|
434
|
+
self
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
373
438
|
end
|
374
439
|
end
|
375
440
|
end
|
@@ -16,7 +16,26 @@ module Squeel
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
def build_default_scope_with_squeel #:nodoc:
|
20
|
+
if defined?(::ActiveRecord::Scoping) &&
|
21
|
+
method(:default_scope).owner != ::ActiveRecord::Scoping::Default::ClassMethods
|
22
|
+
evaluate_default_scope { default_scope }
|
23
|
+
elsif default_scopes.any?
|
24
|
+
evaluate_default_scope do
|
25
|
+
default_scopes.inject(relation) do |default_scope, scope|
|
26
|
+
if scope.is_a?(Hash)
|
27
|
+
default_scope.apply_finder_options(scope)
|
28
|
+
elsif !scope.is_a?(::ActiveRecord::Relation) && scope.respond_to?(:call)
|
29
|
+
default_scope.merge(scope.call, true)
|
30
|
+
else
|
31
|
+
default_scope.merge(scope, true)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
19
38
|
end
|
20
39
|
end
|
21
40
|
end
|
22
|
-
end
|
41
|
+
end
|
@@ -22,10 +22,9 @@ module Squeel
|
|
22
22
|
|
23
23
|
arel.group(*attribute_viz.accept(@group_values.uniq.reject{|g| g.blank?})) unless @group_values.empty?
|
24
24
|
|
25
|
-
order = @
|
26
|
-
order = attribute_viz.accept(order.uniq.reject{|o| o.blank?})
|
25
|
+
order = attribute_viz.accept(@order_values)
|
27
26
|
order = reverse_sql_order(attrs_to_orderings(order)) if @reverse_order_value
|
28
|
-
arel.order(*order) unless order.empty?
|
27
|
+
arel.order(*order.uniq.reject{|o| o.blank?}) unless order.empty?
|
29
28
|
|
30
29
|
build_select(arel, attribute_viz.accept(@select_values.uniq))
|
31
30
|
|
@@ -7,6 +7,7 @@ module Squeel
|
|
7
7
|
include PredicateOperators
|
8
8
|
include Operators
|
9
9
|
include Ordering
|
10
|
+
include Aliasing
|
10
11
|
|
11
12
|
alias :== :eq
|
12
13
|
alias :'^' :not_eq
|
@@ -26,10 +27,6 @@ module Squeel
|
|
26
27
|
# @return [Array] The arguments to be passed to the SQL function
|
27
28
|
attr_reader :args
|
28
29
|
|
29
|
-
# @return [String] The SQL function's alias
|
30
|
-
# @return [NilClass] If no alias
|
31
|
-
attr_reader :alias
|
32
|
-
|
33
30
|
# Create a node representing an SQL Function with the given name and arguments
|
34
31
|
# @param [Symbol] name The function name
|
35
32
|
# @param [Array] args The array of arguments to pass to the function.
|
@@ -37,14 +34,6 @@ module Squeel
|
|
37
34
|
@name, @args = name, args
|
38
35
|
end
|
39
36
|
|
40
|
-
# Set an alias for the function
|
41
|
-
# @param [String, Symbol] The alias name
|
42
|
-
# @return [Function] This function with the new alias value.
|
43
|
-
def as(alias_name)
|
44
|
-
@alias = alias_name.to_s
|
45
|
-
self
|
46
|
-
end
|
47
|
-
|
48
37
|
# expand_hash_conditions_for_aggregates assumes our hash keys can be
|
49
38
|
# converted to symbols, so this has to be implemented, but it doesn't
|
50
39
|
# really have to do anything useful.
|
data/lib/squeel/version.rb
CHANGED
@@ -99,9 +99,8 @@ module Squeel
|
|
99
99
|
quote arg
|
100
100
|
end
|
101
101
|
end
|
102
|
-
func = Arel::Nodes::NamedFunction.new(o.name, args)
|
103
102
|
|
104
|
-
|
103
|
+
Arel::Nodes::NamedFunction.new(o.name, args)
|
105
104
|
end
|
106
105
|
|
107
106
|
# Visit an Operation node. Each operand will be accepted or
|
@@ -134,7 +133,8 @@ module Squeel
|
|
134
133
|
else
|
135
134
|
Arel.sql("#{arel_visitor.accept(args[0])} #{o.operator} #{arel_visitor.accept(args[1])}")
|
136
135
|
end
|
137
|
-
|
136
|
+
|
137
|
+
op
|
138
138
|
end
|
139
139
|
|
140
140
|
# Visit a Squeel Grouping node, resulting in am ARel Grouping node.
|
@@ -152,9 +152,8 @@ module Squeel
|
|
152
152
|
quote arg
|
153
153
|
end
|
154
154
|
end
|
155
|
-
func = Arel::Nodes::NamedFunction.new(o.name, args)
|
156
155
|
|
157
|
-
|
156
|
+
Arel::Nodes::NamedFunction.new(o.name, args)
|
158
157
|
end
|
159
158
|
|
160
159
|
# Visit an ActiveRecord Relation, returning an Arel::SelectManager
|
@@ -199,7 +198,8 @@ module Squeel
|
|
199
198
|
else
|
200
199
|
Arel::Nodes::InfixOperation.new(o.operator, args[0], args[1])
|
201
200
|
end
|
202
|
-
|
201
|
+
|
202
|
+
op
|
203
203
|
end
|
204
204
|
|
205
205
|
# Visit a Squeel And node, returning an ARel Grouping containing an
|
@@ -258,12 +258,25 @@ module Squeel
|
|
258
258
|
block.debug_sql.should eq standard.debug_sql
|
259
259
|
end
|
260
260
|
|
261
|
-
it 'eager loads
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
261
|
+
it 'eager loads belongs_to associations' do
|
262
|
+
queries = queries_for do
|
263
|
+
Article.includes(:person).
|
264
|
+
where{person.name == 'Ernie'}.all
|
265
|
+
end
|
266
|
+
queries.should have(1).item
|
267
|
+
queries.first.should match /LEFT OUTER JOIN "people"/
|
268
|
+
queries.first.should match /"people"."name" = 'Ernie'/
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'eager loads belongs_to associations on models with default_scopes' do
|
272
|
+
queries = queries_for do
|
273
|
+
PersonNamedBill.includes(:parent).
|
274
|
+
where{parent.name == 'Ernie'}.all
|
275
|
+
end
|
276
|
+
queries.should have(1).item
|
277
|
+
queries.first.should match /LEFT OUTER JOIN "people"/
|
278
|
+
queries.first.should match /"people"."name" = 'Bill'/
|
279
|
+
queries.first.should match /"parents_people"."name" = 'Ernie'/
|
267
280
|
end
|
268
281
|
|
269
282
|
it 'eager loads polymorphic belongs_to associations' do
|
@@ -409,10 +422,25 @@ module Squeel
|
|
409
422
|
aric.last_article_id.should eq Article.where(:person_id => 1).last.id
|
410
423
|
end
|
411
424
|
|
412
|
-
|
425
|
+
end
|
426
|
+
|
427
|
+
describe '#count' do
|
428
|
+
|
429
|
+
it 'works with non-strings in select' do
|
413
430
|
Article.select{distinct(title)}.count.should eq 51
|
414
431
|
end
|
415
432
|
|
433
|
+
it 'works with non-strings in wheres' do
|
434
|
+
first_name = Person.first.name
|
435
|
+
Person.where{name.op('=', first_name)}.count.should eq 1
|
436
|
+
end
|
437
|
+
|
438
|
+
it 'works with non-strings in group' do
|
439
|
+
pending "Requires some big hacks to execute_grouped_calculation"
|
440
|
+
counts = Person.group{name.op('||', '-diddly')}.count
|
441
|
+
counts.should eq Person.group{name.op('||', '-diddly')}.count
|
442
|
+
end
|
443
|
+
|
416
444
|
end
|
417
445
|
|
418
446
|
describe '#group' do
|
@@ -476,11 +504,6 @@ module Squeel
|
|
476
504
|
old_and_busted.to_a.should eq new_hotness.to_a
|
477
505
|
end
|
478
506
|
|
479
|
-
it "doesn't break #count if wheres contain InfixOperations" do
|
480
|
-
first_name = Person.first.name
|
481
|
-
Person.where{name.op('=', first_name)}.count.should eq 1
|
482
|
-
end
|
483
|
-
|
484
507
|
end
|
485
508
|
|
486
509
|
describe '#joins' do
|
@@ -570,11 +593,23 @@ module Squeel
|
|
570
593
|
end
|
571
594
|
|
572
595
|
it 'builds options with a block' do
|
573
|
-
block =
|
596
|
+
block = @standard.reorder{id}
|
574
597
|
block.to_sql.should_not eq @standard.to_sql
|
575
598
|
block.to_sql.should match /ORDER BY "people"."id"/
|
576
599
|
end
|
577
600
|
|
601
|
+
it 'drops order by clause when passed nil' do
|
602
|
+
block = @standard.reorder(nil)
|
603
|
+
sql = block.to_sql
|
604
|
+
sql.should_not match /ORDER BY/
|
605
|
+
end
|
606
|
+
|
607
|
+
it 'drops order by clause when passed nil if reversed' do
|
608
|
+
block = @standard.reverse_order.reorder(nil)
|
609
|
+
sql = block.to_sql
|
610
|
+
sql.should_not match /ORDER BY/
|
611
|
+
end
|
612
|
+
|
578
613
|
end
|
579
614
|
|
580
615
|
describe '#build_where' do
|
@@ -689,6 +724,13 @@ module Squeel
|
|
689
724
|
sql.should match /Bert/
|
690
725
|
end
|
691
726
|
|
727
|
+
it 'uses the given equality condition in the case of a conflicting where from a default scope in AR >= 3.1' do
|
728
|
+
relation = PersonNamedBill.where{name == 'Ernie'}
|
729
|
+
sql = relation.to_sql
|
730
|
+
sql.should_not match /Bill/
|
731
|
+
sql.should match /Ernie/
|
732
|
+
end unless ::ActiveRecord::VERSION::MINOR == 0
|
733
|
+
|
692
734
|
it "doesn't ruin everything when a scope returns nil" do
|
693
735
|
relation = Person.nil_scope
|
694
736
|
relation.should eq Person.scoped
|
@@ -153,20 +153,6 @@ module Squeel
|
|
153
153
|
negated.expr.should eq @f
|
154
154
|
end
|
155
155
|
|
156
|
-
describe '#as' do
|
157
|
-
|
158
|
-
it 'aliases the function' do
|
159
|
-
@f.as('the_alias')
|
160
|
-
@f.alias.should eq 'the_alias'
|
161
|
-
end
|
162
|
-
|
163
|
-
it 'casts the alias to a string' do
|
164
|
-
@f.as(:the_alias)
|
165
|
-
@f.alias.should eq 'the_alias'
|
166
|
-
end
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
156
|
end
|
171
157
|
end
|
172
158
|
end
|
@@ -153,20 +153,6 @@ module Squeel
|
|
153
153
|
negated.expr.should eq @o
|
154
154
|
end
|
155
155
|
|
156
|
-
describe '#as' do
|
157
|
-
|
158
|
-
it 'aliases the function' do
|
159
|
-
@o.as('the_alias')
|
160
|
-
@o.alias.should eq 'the_alias'
|
161
|
-
end
|
162
|
-
|
163
|
-
it 'casts the alias to a string' do
|
164
|
-
@o.as(:the_alias)
|
165
|
-
@o.alias.should eq 'the_alias'
|
166
|
-
end
|
167
|
-
|
168
|
-
end
|
169
|
-
|
170
156
|
end
|
171
157
|
end
|
172
158
|
end
|
data/spec/support/schema.rb
CHANGED
@@ -37,7 +37,8 @@ end
|
|
37
37
|
|
38
38
|
class PersonNamedBill < ActiveRecord::Base
|
39
39
|
self.table_name = 'people'
|
40
|
-
|
40
|
+
belongs_to :parent, :class_name => 'Person', :foreign_key => :parent_id
|
41
|
+
default_scope where{name == 'Bill'}
|
41
42
|
end
|
42
43
|
|
43
44
|
class Message < ActiveRecord::Base
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: squeel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-07-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -240,7 +240,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
240
240
|
version: '0'
|
241
241
|
segments:
|
242
242
|
- 0
|
243
|
-
hash: -
|
243
|
+
hash: -1051407331683440462
|
244
244
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
245
245
|
none: false
|
246
246
|
requirements:
|
@@ -249,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
249
249
|
version: '0'
|
250
250
|
segments:
|
251
251
|
- 0
|
252
|
-
hash: -
|
252
|
+
hash: -1051407331683440462
|
253
253
|
requirements: []
|
254
254
|
rubyforge_project: squeel
|
255
255
|
rubygems_version: 1.8.24
|