arel-helpers 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 61f2686d698c0636f36437e6d74562670d5ff0c4
4
- data.tar.gz: 1f9126e6e36e9c45104fd11b5ffeb7afb6d82118
3
+ metadata.gz: a7fcf6cccc8b45ef008f68a1da1ef9e8b468d474
4
+ data.tar.gz: dc76542898067426f8715ccb4b91b2b1d48f1787
5
5
  SHA512:
6
- metadata.gz: e4fe390a4e6fb4e1cd8d8ddd105e1172b26e5c378ce74127fad57ed6cc5bcb2469702f264e02f13fb655e3f523d4b75e237ea7ccbce2029d1f60299b14d4f636
7
- data.tar.gz: 6b2f0c69c50bdb7e36b8d58614b986861a699bf4f39b930c8c1c7caba393ef8bd189df3f2142035a46b5f775408d046454dfa6f22aa7d997193c369b42582870
6
+ metadata.gz: 3c95d188bfb80db50e13f8c98d7847bca7abc6c0b95502c22efd0eef043f1a5ec0b71b5c71410cfeaeabfb9533ae9ee02099d5fc55644f886fe95599ecd1631a
7
+ data.tar.gz: b74df2e5fd0224f8945219944888eea41be7e78532f4e277ae1e17eb3fc5ba792a35e0957e08b1b0dc87cd8a376d4b769c99fb0981c12475ca54efca404e084d
data/History.txt CHANGED
@@ -4,4 +4,8 @@
4
4
 
5
5
  == 1.1.0
6
6
 
7
- * Adding the QueryBuilder class.
7
+ * Adding the QueryBuilder class.
8
+
9
+ == 1.2.0
10
+
11
+ * Adding Rails 4 support.
data/README.md CHANGED
@@ -0,0 +1,154 @@
1
+
2
+
3
+ ## arel-helpers [![Build Status](https://secure.travis-ci.org/camertron/arel-helpers.png?branch=master)](http://travis-ci.org/camertron/arel-helpers)
4
+
5
+ Useful tools to help construct database queries with ActiveRecord and Arel.
6
+
7
+ ## Installation
8
+
9
+ `gem install arel-helpers`
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ require 'arel-helpers'
15
+ ```
16
+
17
+ ### ArelTable Helper
18
+
19
+ Usually you'd reference database columns in Arel via the `#arel_table` method on your ActiveRecord models. For example:
20
+
21
+ ```ruby
22
+ class Post < ActiveRecord::Base
23
+ ...
24
+ end
25
+
26
+ Post.where(Post.arel_table[:id].eq(1))
27
+ ```
28
+
29
+ Typing ".arel_table" over and over again can get pretty old and make constructing queries unnecessarily verbose. Try using the `ArelTable` helper to clean things up a bit:
30
+
31
+ ```ruby
32
+ class Post < ActiveRecord::Base
33
+ include ArelHelpers::ArelTable
34
+ ...
35
+ end
36
+
37
+ Post.where(Post[:id].eq(1))
38
+ ```
39
+
40
+ ### JoinAssociation Helper
41
+
42
+ Using pure Arel is probably one of the only ways to do an outer join with ActiveRecord. For example, let's say we have these two models:
43
+
44
+ ```ruby
45
+ class Post < ActiveRecord::Base
46
+ has_many :comments
47
+ end
48
+
49
+ class Comment < ActiveRecord::Base
50
+ belongs_to :post
51
+ end
52
+ ```
53
+
54
+ A join between posts and comments might look like this:
55
+
56
+ ```ruby
57
+ Post.joins(:comments)
58
+ ```
59
+
60
+ ActiveRecord introspects the association between posts and comments and automatically chooses the right columns to use in the join conditions.
61
+
62
+ Things start to get messy however if you wanted to do an outer join instead of the default inner join. Your query might look like this:
63
+
64
+ ```ruby
65
+ Post
66
+ .joins(
67
+ Post.arel_table.join(Comments.arel_table, Arel::OuterJoin)
68
+ .on(Post[:id].eq(Coments[:post_id]))
69
+ .join_sources
70
+ )
71
+ ```
72
+
73
+ Such verbose. Much code. Very bloat. Wow. We've lost all the awesome association introspection that ActiveRecord would otherwise have given us. Enter `ArelHelpers::JoinAssociation`:
74
+
75
+ ```ruby
76
+ include ArelHelpers::JoinAssociation
77
+ Post.joins(join_association(Post, :comments, Arel::OuterJoin))
78
+ ```
79
+
80
+ Easy peasy.
81
+
82
+ `JoinAssociation` also allows you to customize the join conditions via a block:
83
+
84
+ ```ruby
85
+ Post.joins(
86
+ join_association(Post, :comments, Arel::OuterJoin) do |assoc_name, join_conditions|
87
+ join_conditions.and(Post[:author_id].eq(4))
88
+ end
89
+ )
90
+ ```
91
+
92
+ ### Query Builders
93
+
94
+ ArelHelpers also contains a very simple class that's designed to provide a light framework for constructing queries using the builder pattern. For example, let's write a class that encapsulates generating queries for blog posts:
95
+
96
+ ```ruby
97
+ class PostQueryBuilder < ArelHelpers::QueryBuilder
98
+ def initialize(query = nil)
99
+ # whatever you want your initial query to be
100
+ super(query || post.unscoped)
101
+ end
102
+
103
+ def with_title_matching(title)
104
+ reflect(
105
+ query.where(post[:title].matches("%#{title}%"))
106
+ )
107
+ end
108
+
109
+ def with_comments_by(usernames)
110
+ reflect(
111
+ query
112
+ .joins(:comments => :author)
113
+ .where(Author[:username].in(usernames))
114
+ )
115
+ end
116
+
117
+ def since_yesterday
118
+ reflect(
119
+ query.where(post[:created_at].gteq(Date.yesterday))
120
+ )
121
+ end
122
+
123
+ private
124
+
125
+ def author
126
+ Author
127
+ end
128
+
129
+ def post
130
+ Post
131
+ end
132
+ end
133
+ ```
134
+
135
+ The `#reflect` method creates a new instance of `PostQueryBuilder`, copies the query into it and returns the new query builder instance. This allows you to chain your method calls:
136
+
137
+ ```ruby
138
+ PostQueryBuilder.new
139
+ .with_comments_by(['camertron', 'catwithtail'])
140
+ .with_title_matching("arel rocks")
141
+ .since_yesterday
142
+ ```
143
+
144
+ ## Requirements
145
+
146
+ No external requirements. Depends on SQLite for testing purposes.
147
+
148
+ ## Running Tests
149
+
150
+ `bundle exec rspec`
151
+
152
+ ## Authors
153
+
154
+ * Cameron C. Dutro: http://github.com/camertron
data/arel-helpers.gemspec CHANGED
@@ -13,7 +13,11 @@ Gem::Specification.new do |s|
13
13
  s.platform = Gem::Platform::RUBY
14
14
  s.has_rdoc = true
15
15
 
16
- s.add_dependency 'activerecord', '~> 3.0'
16
+ if ENV["AR"]
17
+ s.add_dependency 'activerecord', ENV["AR"]
18
+ else
19
+ s.add_dependency 'activerecord', '>= 3.1.0', '<= 4.1.0'
20
+ end
17
21
 
18
22
  s.require_path = 'lib'
19
23
  s.files = Dir["{lib,spec}/**/*", "Gemfile", "History.txt", "README.md", "Rakefile", "arel-helpers.gemspec"]
@@ -6,9 +6,19 @@ module ArelHelpers
6
6
  # activerecord uses JoinDependency to automagically generate inner join statements for
7
7
  # any type of association (belongs_to, has_many, and has_and_belongs_to_many).
8
8
  # For example, for HABTM associations, two join statements are required.
9
- # This method encapsulates that functionality and returns a SelectManager for chaining.
9
+ # This method encapsulates that functionality and yields an intermediate object for chaining.
10
10
  # It also allows you to use an outer join instead of the default inner via the join_type arg.
11
- def join_association(table, association, join_type = Arel::InnerJoin)
11
+ def join_association(table, association, join_type = Arel::InnerJoin, &block)
12
+ if ActiveRecord::VERSION::STRING >= '4.1.0'
13
+ join_association_4_1(table, association, join_type, &block)
14
+ else
15
+ join_association_3_1(table, association, join_type, &block)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def join_association_3_1(table, association, join_type)
12
22
  associations = association.is_a?(Array) ? association : [association]
13
23
  join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, [])
14
24
  manager = Arel::SelectManager.new(table)
@@ -29,5 +39,20 @@ module ArelHelpers
29
39
  end
30
40
  end
31
41
 
42
+ def join_association_4_1(table, association, join_type)
43
+ associations = association.is_a?(Array) ? association : [association]
44
+ join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, [])
45
+
46
+ join_dependency.join_constraints([]).map do |constraint|
47
+ right = if block_given?
48
+ yield constraint.left.name.to_sym, constraint.right
49
+ else
50
+ constraint.right
51
+ end
52
+
53
+ join_type.new(constraint.left, right)
54
+ end
55
+ end
56
+
32
57
  end
33
58
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module ArelHelpers
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Dutro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-22 00:00:00.000000000 Z
11
+ date: 2014-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: 3.1.0
20
+ - - <=
21
+ - !ruby/object:Gem::Version
22
+ version: 4.1.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - ~>
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.1.0
30
+ - - <=
25
31
  - !ruby/object:Gem::Version
26
- version: '3.0'
32
+ version: 4.1.0
27
33
  description: Useful tools to help construct database queries with ActiveRecord and
28
34
  Arel.
29
35
  email:
@@ -32,20 +38,20 @@ executables: []
32
38
  extensions: []
33
39
  extra_rdoc_files: []
34
40
  files:
35
- - Gemfile
36
- - History.txt
37
- - README.md
38
- - Rakefile
39
- - arel-helpers.gemspec
40
- - lib/arel-helpers.rb
41
41
  - lib/arel-helpers/arel_table.rb
42
42
  - lib/arel-helpers/join_association.rb
43
43
  - lib/arel-helpers/query_builder.rb
44
44
  - lib/arel-helpers/version.rb
45
+ - lib/arel-helpers.rb
45
46
  - spec/arel_table_spec.rb
46
47
  - spec/join_association_spec.rb
47
48
  - spec/query_builder_spec.rb
48
49
  - spec/spec_helper.rb
50
+ - Gemfile
51
+ - History.txt
52
+ - README.md
53
+ - Rakefile
54
+ - arel-helpers.gemspec
49
55
  homepage: http://github.com/camertron
50
56
  licenses: []
51
57
  metadata: {}
@@ -65,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
71
  version: '0'
66
72
  requirements: []
67
73
  rubyforge_project:
68
- rubygems_version: 2.2.2
74
+ rubygems_version: 2.0.3
69
75
  signing_key:
70
76
  specification_version: 4
71
77
  summary: Useful tools to help construct database queries with ActiveRecord and Arel.