baby_squeel 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4dec1d36d240f113d9122c83549c06601f29124c
4
- data.tar.gz: f97d4bc708832c1895e0e612c6bd76dfe63b6877
3
+ metadata.gz: 3569d1726ce4c979428cbc2fed31fe8103f16405
4
+ data.tar.gz: 7d60acb4736d2a7cdda1e921bcb32ac1b8597601
5
5
  SHA512:
6
- metadata.gz: 7be1b2e3d861f50328cb1a9b05f8e02099a1db3c33dfeda3259a77667291b8f3b373d3e0a395230b1b64af7b8d8c2d559f52e31752c7e20401371e5eaa1fecaf
7
- data.tar.gz: 877ad6134d70a905a9142f92265e059ef48e49edd9ef513445a966b0a2a22758c0e1792be9180b749be5d2673e5e817a15550fe93e465eb61e2440709bd9b770
6
+ metadata.gz: 81b72fb9e8b0f80dc8a0c5e52b215ed89e8f8801407ec2a60747f06171f35b9e6f8d0970c7009573092b17eaaa67ea8fabfa8dcf542b1aa0396b777df966bd4a
7
+ data.tar.gz: fdcbff4355e934d51d6f6e57e19fdbda28a93eac0acb3ea91b4fc1d1d7c9ed84ae06c75dcb500a72325577374df38c0969ebef9dbee45b08a7cd0845de27c374
data/.rubocop.yml CHANGED
@@ -7,9 +7,15 @@ Style/BlockDelimiters:
7
7
  Style/Documentation:
8
8
  Enabled: false
9
9
 
10
+ Style/SpecialGlobalVars:
11
+ Enabled: false
12
+
10
13
  Style/NilComparison:
11
14
  Exclude:
12
15
  - spec/**/*
13
16
 
14
17
  Metrics/LineLength:
15
18
  Max: 100
19
+
20
+ Metrics/AbcSize:
21
+ Enabled: false
data/.travis.yml CHANGED
@@ -16,4 +16,5 @@ env:
16
16
  - AR=4.1.15
17
17
  - AR=4.2.0
18
18
  - AR=4.2.6
19
+ - AR=5.0.0.beta2
19
20
  - AR=5.0.0.beta3
data/README.md CHANGED
@@ -53,41 +53,6 @@ Post.joins(:author).selecting { [id, author.id] }
53
53
  # INNER JOIN "authors" ON "posts"."author_id" = "authors"."id"
54
54
  ```
55
55
 
56
- #### Joins
57
-
58
- ```ruby
59
- Post.joining { author }
60
- # SELECT "posts".* FROM "posts"
61
- # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
62
-
63
- Post.joining { [author.outer, comments] }
64
- # SELECT "posts".* FROM "posts"
65
- # LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
66
- # INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
67
-
68
- Post.joining { author.comments }
69
- # SELECT "posts".* FROM "posts"
70
- # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
71
- # INNER JOIN "comments" ON "comments"."author_id" = "authors"."id"
72
-
73
- Post.joining { author.outer.comments.outer }
74
- # SELECT "posts".* FROM "posts"
75
- # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
76
- # LEFT OUTER JOIN "comments" ON "comments"."author_id" = "authors"."id"
77
-
78
- Post.joining { author.comments.outer }
79
- # SELECT "posts".* FROM "posts"
80
- # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
81
- # LEFT OUTER JOIN "comments" ON "comments"."author_id" = "authors"."id"
82
-
83
- Post.joining { author.alias('a').on((author.id == author_id) | (author.name == title)) }
84
- # SELECT "posts".* FROM "posts"
85
- # INNER JOIN "authors" "a" ON (
86
- # "authors"."id" = "posts"."author_id" OR
87
- # "authors"."name" = "posts"."title"
88
- # )
89
- ```
90
-
91
56
  #### Wheres
92
57
 
93
58
  ```ruby
@@ -110,6 +75,16 @@ Post.joins(:author).where.has { author.name == 'Ray' }
110
75
  # WHERE "authors"."name" = 'Ray'
111
76
  ```
112
77
 
78
+ Here's the best part. Where conditions will always reference the correct table alias for a given association:
79
+
80
+ ```ruby
81
+ Post.joins(author: :posts).where.has { author.posts.title =~ '%fun%' }
82
+ # SELECT "posts".* FROM "posts"
83
+ # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
84
+ # INNER JOIN "posts" "posts_authors" ON "posts_authors"."author_id" = "authors"."id"
85
+ # WHERE ("posts_authors"."title" LIKE '%fun%')
86
+ ```
87
+
113
88
  #### Orders
114
89
 
115
90
  ```ruby
@@ -130,6 +105,47 @@ Post.joins(:author).ordering { author.id.desc }
130
105
  # ORDER BY "authors"."id" DESC
131
106
  ```
132
107
 
108
+
109
+ #### Joins
110
+
111
+ ```ruby
112
+ Post.joining { author }
113
+ # SELECT "posts".* FROM "posts"
114
+ # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
115
+
116
+ Post.joining { [author.outer, comments] }
117
+ # SELECT "posts".* FROM "posts"
118
+ # LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
119
+ # INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
120
+
121
+ Post.joining { author.comments }
122
+ # SELECT "posts".* FROM "posts"
123
+ # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
124
+ # INNER JOIN "comments" ON "comments"."author_id" = "authors"."id"
125
+
126
+ Post.joining { author.outer.comments.outer }
127
+ # SELECT "posts".* FROM "posts"
128
+ # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
129
+ # LEFT OUTER JOIN "comments" ON "comments"."author_id" = "authors"."id"
130
+
131
+ Post.joining { author.comments.outer }
132
+ # SELECT "posts".* FROM "posts"
133
+ # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
134
+ # LEFT OUTER JOIN "comments" ON "comments"."author_id" = "authors"."id"
135
+
136
+ Post.joining { author.outer.posts }
137
+ # SELECT "posts".* FROM "posts"
138
+ # LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
139
+ # INNER JOIN "posts" "posts_authors" ON "posts_authors"."author_id" = "authors"."id"
140
+
141
+ Post.joining { author.alias('a').on((author.id == author_id) | (author.name == title)) }
142
+ # SELECT "posts".* FROM "posts"
143
+ # INNER JOIN "authors" "a" ON (
144
+ # "authors"."id" = "posts"."author_id" OR
145
+ # "authors"."name" = "posts"."title"
146
+ # )
147
+ ```
148
+
133
149
  #### Functions
134
150
 
135
151
  ```ruby
@@ -158,7 +174,7 @@ You can also run `bin/console` to open up a prompt where you'll have access to s
158
174
 
159
175
  ## Todo
160
176
 
161
- I'd like to support complex joins with explicit outer joins and aliasing.
177
+ + Subqueries
162
178
 
163
179
  ## Contributing
164
180
 
data/Rakefile CHANGED
@@ -15,9 +15,10 @@ def run_version(version, cmd)
15
15
  system({ 'AR' => version }, cmd)
16
16
  end
17
17
 
18
- abort "\nFAILED: #{display}" unless $CHILD_STATUS.success?
18
+ abort "\nFAILED: #{display}" unless $?.success?
19
19
  end
20
20
 
21
+ desc 'Run against all ActiveRecord versions'
21
22
  task 'spec:matrix' do
22
23
  travis = YAML.load_file '.travis.yml'
23
24
 
data/lib/baby_squeel.rb CHANGED
@@ -7,4 +7,5 @@ module BabySqueel
7
7
  end
8
8
 
9
9
  ::ActiveRecord::Base.extend BabySqueel::ActiveRecord::QueryMethods
10
+ ::ActiveRecord::Relation.prepend BabySqueel::ActiveRecord::QueryMethods
10
11
  ::ActiveRecord::QueryMethods::WhereChain.prepend BabySqueel::ActiveRecord::WhereChain
@@ -3,14 +3,17 @@ require 'baby_squeel/dsl'
3
3
  module BabySqueel
4
4
  module ActiveRecord
5
5
  module QueryMethods
6
+ # Constructs Arel for ActiveRecord::Base#joins using the DSL.
6
7
  def joining(&block)
7
- joins DSL.evaluate(self, &block)
8
+ joins DSL.evaluate(unscoped, &block)
8
9
  end
9
10
 
11
+ # Constructs Arel for ActiveRecord::Base#select using the DSL.
10
12
  def selecting(&block)
11
13
  select DSL.evaluate(self, &block)
12
14
  end
13
15
 
16
+ # Constructs Arel for ActiveRecord::Base#order using the DSL.
14
17
  def ordering(&block)
15
18
  order DSL.evaluate(self, &block)
16
19
  end
@@ -18,6 +21,7 @@ module BabySqueel
18
21
 
19
22
  module WhereChain
20
23
  if ::ActiveRecord::VERSION::MAJOR > 4
24
+ # Constructs Arel for ActiveRecord::Base#where using the DSL.
21
25
  def has(&block)
22
26
  opts = DSL.evaluate(@scope, &block)
23
27
  factory = @scope.send(:where_clause_factory)
@@ -25,6 +29,7 @@ module BabySqueel
25
29
  @scope
26
30
  end
27
31
  else
32
+ # Constructs Arel for ActiveRecord::Base#where using the DSL.
28
33
  def has(&block)
29
34
  @scope.where_values += [DSL.evaluate(@scope, &block)]
30
35
  @scope
@@ -1,42 +1,45 @@
1
1
  require 'baby_squeel/table'
2
- require 'baby_squeel/join_dependency'
3
2
 
4
3
  module BabySqueel
5
- class AliasingError < StandardError
6
- MESSAGE =
7
- 'Attempted to alias \'%{association}\' as \'%{alias_name}\', but the ' \
8
- 'association was implicitly joined. Either join the association ' \
9
- 'with `on` or remove the alias.'.freeze
10
-
11
- def initialize(association, alias_name)
12
- super format(MESSAGE, association: association, alias_name: alias_name)
13
- end
14
- end
15
-
16
4
  class Association < Table
17
- def initialize(parent, reflection)
18
- @parent = parent
19
- @reflection = reflection
20
- super(@reflection.klass)
21
- end
22
-
23
- def _arel
24
- props[:on] ? super : ([*@parent._arel] + join_constraints)
5
+ class AliasingError < StandardError
6
+ MESSAGE =
7
+ 'Attempted to alias \'%{association}\' as \'%{alias_name}\', but the ' \
8
+ 'association was implicitly joined. Either join the association ' \
9
+ 'with `on` or remove the alias.'.freeze
10
+
11
+ def initialize(association, alias_name)
12
+ super format(MESSAGE, association: association, alias_name: alias_name)
13
+ end
25
14
  end
26
15
 
27
- private
28
-
29
- def join_constraints
30
- if props[:table].is_a? Arel::Nodes::TableAlias
31
- raise AliasingError.new(@reflection.name, props[:table].right)
32
- end
16
+ attr_reader :_reflection
33
17
 
34
- JoinDependency.new(@scope, @reflection, props[:join]).constraints
18
+ def initialize(parent, reflection)
19
+ @parent = parent
20
+ @_reflection = reflection
21
+ super(@_reflection.klass)
35
22
  end
36
23
 
37
- def spawn
38
- Association.new(@parent, @reflection).tap do |table|
39
- table.props = props
24
+ # Intelligently constructs Arel nodes. There are three outcomes:
25
+ #
26
+ # 1. The user explicitly constructed their join using #on.
27
+ # See BabySqueel::Table#_arel.
28
+ #
29
+ # 2. The user aliased an implicitly joined association. ActiveRecord's
30
+ # join dependency gives us no way of handling this, so we have to
31
+ # throw an error.
32
+ #
33
+ # 3. The user implicitly joined this association, so we pass this
34
+ # association up the tree until it hits the top-level BabySqueel::Table.
35
+ # Once it gets there, Arel join nodes will be constructed.
36
+ def _arel(associations = [])
37
+ if _on
38
+ super
39
+ elsif _table.is_a? Arel::Nodes::TableAlias
40
+ raise AliasingError.new(_reflection.name, _table.right)
41
+ else
42
+ @parent._arel([self, *associations])
40
43
  end
41
44
  end
42
45
  end
@@ -4,14 +4,28 @@ require 'baby_squeel/association'
4
4
 
5
5
  module BabySqueel
6
6
  class DSL < Table
7
+ # Evaluates a block in the context of a new DSL instance.
7
8
  def self.evaluate(scope, &block)
8
9
  new(scope).evaluate(&block)
9
10
  end
10
11
 
12
+ # Create a SQL function. See Arel::Nodes::NamedFunction.
13
+ #
14
+ # ==== Arguments
15
+ #
16
+ # * +name+ - The name of a SQL function (ex. coalesce).
17
+ # * +args+ - The arguments to be passed to the SQL function.
18
+ #
19
+ # ==== Example
20
+ # Post.select { func('coalesce', id, 1) }
21
+ # #=> SELECT COALESCE("posts"."id", 1) FROM "posts"
22
+ #
11
23
  def func(name, *args)
12
24
  Nodes.wrap Arel::Nodes::NamedFunction.new(name.to_s, args)
13
25
  end
14
26
 
27
+ # Evaluates a DSL block. If arity is given, this method
28
+ # `yield` itself, rather than `instance_eval`.
15
29
  def evaluate(&block)
16
30
  if block.arity.zero?
17
31
  Nodes.unwrap instance_eval(&block)
@@ -1,55 +1,39 @@
1
- # Props to Arel Helpers
2
- # https://github.com/camertron/arel-helpers/blob/master/lib/arel-helpers/join_association.rb
3
- #
4
- # This is really, really ugly.
5
- #
6
1
  module BabySqueel
7
2
  class JoinDependency
8
- def initialize(scope, reflection, join_type)
3
+ def initialize(scope, associations = [])
9
4
  @scope = scope
10
- @reflection = reflection
11
- @join_type = join_type
5
+ @associations = associations
12
6
  end
13
7
 
14
- if ::ActiveRecord::VERSION::MAJOR > 4
15
- def constraints
16
- dependency.join_constraints([], @join_type).flat_map(&:joins)
17
- end
18
- elsif ::ActiveRecord::VERSION::STRING >= '4.2.0'
19
- def constraints
20
- dependency.join_constraints([]).flat_map do |constraint|
21
- constraint.joins.map { |join| rebuild join }
22
- end
23
- end
24
- elsif ::ActiveRecord::VERSION::STRING >= '4.1.0'
25
- def constraints
26
- dependency.join_constraints([]).flat_map { |join| rebuild join }
27
- end
28
- else
29
- def constraints
30
- manager = Arel::SelectManager.new(@scope)
31
-
32
- dependency.join_associations.each do |assoc|
33
- assoc.join_type = @join_type
34
- assoc.join_to(manager)
35
- end
36
-
37
- manager.join_sources
8
+ # Converts an array of BabySqueel::Associations into an array
9
+ # of Arel join nodes.
10
+ #
11
+ # Each association is built individually so that the correct
12
+ # Arel join node will be used for each individual association.
13
+ def constraints
14
+ @associations.each.with_index.inject([]) do |joins, (assoc, i)|
15
+ inject @associations[0..i], joins, assoc._join
38
16
  end
39
17
  end
40
18
 
41
19
  private
42
20
 
43
- def rebuild(join)
44
- @join_type.new(join.left, join.right)
21
+ def inject(associations, theirs, join_node)
22
+ names = join_names associations
23
+ mine = build names, join_node
24
+ theirs + mine[theirs.length..-1]
45
25
  end
46
26
 
47
- def dependency
48
- ::ActiveRecord::Associations::JoinDependency.new(
49
- @reflection.active_record,
50
- [@reflection.name],
51
- []
52
- )
27
+ def build(names, join_node)
28
+ @scope.joins(names).join_sources.map do |join|
29
+ join_node.new(join.left, join.right)
30
+ end
31
+ end
32
+
33
+ def join_names(associations = [])
34
+ associations.reverse.inject({}) do |names, assoc|
35
+ { assoc._reflection.name => names }
36
+ end
53
37
  end
54
38
  end
55
39
  end
@@ -3,6 +3,8 @@ require 'baby_squeel/operators'
3
3
  module BabySqueel
4
4
  module Nodes
5
5
  class << self
6
+ # Wraps an Arel node in a Proxy so that it can
7
+ # be extended.
6
8
  def wrap(arel)
7
9
  if arel.class.parents.include?(Arel)
8
10
  Generic.new(arel)
@@ -11,6 +13,8 @@ module BabySqueel
11
13
  end
12
14
  end
13
15
 
16
+ # Unwraps a BabySqueel::Proxy before being passed to
17
+ # ActiveRecord.
14
18
  def unwrap(node)
15
19
  if node.respond_to? :_arel
16
20
  node._arel
@@ -22,9 +26,8 @@ module BabySqueel
22
26
  end
23
27
  end
24
28
 
25
- # This proxy class allows us to quack like
26
- # any arel object. When a method missing is
27
- # hit, we'll instantiate a new proxy object.
29
+ # This proxy class allows us to quack like any arel object. When a
30
+ # method missing is hit, we'll instantiate a new proxy object.
28
31
  class Proxy < ActiveSupport::ProxyObject
29
32
  # Resolve constants the normal way
30
33
  def self.const_missing(name)
@@ -52,11 +55,11 @@ module BabySqueel
52
55
  end
53
56
  end
54
57
 
55
- # This is a generic proxy class that includes
56
- # all possible modules. In the future, these
57
- # proxy classes should be more specific and
58
- # only include necessary/applicable modules.
58
+ # This is a generic proxy class that includes all possible modules.
59
+ # In the future, these proxy classes should be more specific and only
60
+ # include necessary/applicable modules.
59
61
  class Generic < Proxy
62
+ extend Operators::ArelAliasing
60
63
  include Arel::OrderPredications
61
64
  include Operators::Comparison
62
65
  include Operators::Equality
@@ -64,5 +67,23 @@ module BabySqueel
64
67
  include Operators::Grouping
65
68
  include Operators::Matching
66
69
  end
70
+
71
+ class Attribute < Generic
72
+ def initialize(parent, name)
73
+ @parent = parent
74
+ @name = name
75
+ super(parent._table[name])
76
+ end
77
+
78
+ def _arel
79
+ parent_arel = @parent._arel
80
+
81
+ if parent_arel && parent_arel.last
82
+ parent_arel.last.left[@name]
83
+ else
84
+ super
85
+ end
86
+ end
87
+ end
67
88
  end
68
89
  end
@@ -1,6 +1,17 @@
1
1
  module BabySqueel
2
2
  module Operators
3
3
  module ArelAliasing
4
+ # Allows the creation of shorthands for Arel methods.
5
+ #
6
+ # ==== Arguments
7
+ #
8
+ # * +operator+ - A custom operator.
9
+ # * +arel_name+ - The name of the Arel method you want to alias.
10
+ #
11
+ # ==== Example
12
+ # BabySqueel::Nodes::Generic.arel_alias :unlike, :does_not_match
13
+ # Post.where { title.unlike 'something' }
14
+ #
4
15
  def arel_alias(operator, arel_name)
5
16
  define_method operator do |other|
6
17
  send(arel_name, other)
@@ -23,6 +34,17 @@ module BabySqueel
23
34
  end
24
35
 
25
36
  module Generic
37
+ # Create a SQL operation. See Arel::Nodes::InfixOperation.
38
+ #
39
+ # ==== Arguments
40
+ #
41
+ # * +operator+ - A SQL operator.
42
+ # * +other+ - The argument to be passed to the SQL operator.
43
+ #
44
+ # ==== Example
45
+ # Post.select { title.op('||', 'diddly') }
46
+ # #=> SELECT "posts"."title" || 'diddly' FROM "posts"
47
+ #
26
48
  def op(operator, other)
27
49
  Nodes.wrap Arel::Nodes::InfixOperation.new(operator, self, other)
28
50
  end
@@ -1,3 +1,5 @@
1
+ require 'baby_squeel/join_dependency'
2
+
1
3
  module BabySqueel
2
4
  class AssociationNotFoundError < StandardError
3
5
  def initialize(scope, name)
@@ -6,16 +8,21 @@ module BabySqueel
6
8
  end
7
9
 
8
10
  class Table
9
- attr_writer :props
11
+ attr_accessor :_on, :_join, :_table
10
12
 
11
13
  def initialize(scope)
12
14
  @scope = scope
15
+ @_table = scope.arel_table
16
+ @_join = Arel::Nodes::InnerJoin
13
17
  end
14
18
 
19
+ # See Arel::Table#[]
15
20
  def [](key)
16
- Nodes.wrap props[:table][key]
21
+ Nodes::Attribute.new(self, key)
17
22
  end
18
23
 
24
+ # Constructs a new BabySqueel::Association. Raises
25
+ # an exception if the association is not found.
19
26
  def association(name)
20
27
  if reflection = @scope.reflect_on_association(name)
21
28
  Association.new(self, reflection)
@@ -24,58 +31,63 @@ module BabySqueel
24
31
  end
25
32
  end
26
33
 
34
+ # Alias a table. This is only possible when joining
35
+ # an association explicitly.
27
36
  def alias(alias_name)
28
- spawn.alias! alias_name
37
+ clone.alias! alias_name
29
38
  end
30
39
 
31
40
  def alias!(alias_name)
32
- props.store :table, props[:table].alias(alias_name)
41
+ self._table = _table.alias(alias_name)
33
42
  self
34
43
  end
35
44
 
45
+ # Instruct the table to be joined with an INNER JOIN.
36
46
  def outer
37
- spawn.outer!
47
+ clone.outer!
38
48
  end
39
49
 
40
50
  def outer!
41
- props.store :join, Arel::Nodes::OuterJoin
51
+ self._join = Arel::Nodes::OuterJoin
42
52
  self
43
53
  end
44
54
 
55
+ # Instruct the table to be joined with an INNER JOIN.
45
56
  def inner
46
- spawn.inner!
57
+ clone.inner!
47
58
  end
48
59
 
49
60
  def inner!
50
- props.store :join, Arel::Nodes::InnerJoin
61
+ self._join = Arel::Nodes::InnerJoin
51
62
  self
52
63
  end
53
64
 
65
+ # Specify an explicit join.
54
66
  def on(node)
55
- spawn.on! node
67
+ clone.on! node
56
68
  end
57
69
 
58
70
  def on!(node)
59
- props.store :on, Arel::Nodes::On.new(node)
71
+ self._on = Arel::Nodes::On.new(node)
60
72
  self
61
73
  end
62
74
 
63
- def _arel
64
- props[:join].new(props[:table], props[:on]) if props[:on]
75
+ # This method will be invoked by BabySqueel::Nodes::unwrap. When called,
76
+ # there are two possible outcomes:
77
+ #
78
+ # 1. Join explicitly using an on clause.
79
+ # 2. Resolve the assocition's join clauses using ActiveRecord.
80
+ #
81
+ def _arel(associations = [])
82
+ if _on
83
+ _join.new(_table, _on)
84
+ else
85
+ JoinDependency.new(@scope, associations).constraints
86
+ end
65
87
  end
66
88
 
67
89
  private
68
90
 
69
- def props
70
- @props ||= { table: @scope.arel_table, join: Arel::Nodes::InnerJoin }
71
- end
72
-
73
- def spawn
74
- Table.new(@scope).tap do |table|
75
- table.props = props
76
- end
77
- end
78
-
79
91
  def resolve(name)
80
92
  if @scope.column_names.include?(name.to_s)
81
93
  self[name]
@@ -1,3 +1,3 @@
1
1
  module BabySqueel
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baby_squeel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ray Zane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-03-16 00:00:00.000000000 Z
11
+ date: 2016-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord