arel-helpers 1.0.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 +7 -0
- data/Gemfile +14 -0
- data/History.txt +3 -0
- data/README.md +0 -0
- data/Rakefile +18 -0
- data/arel-helpers.gemspec +20 -0
- data/lib/arel-helpers/arel_table.rb +17 -0
- data/lib/arel-helpers/join_association.rb +33 -0
- data/lib/arel-helpers/version.rb +5 -0
- data/lib/arel-helpers.rb +8 -0
- data/spec/arel_table_spec.rb +13 -0
- data/spec/join_association_spec.rb +51 -0
- data/spec/spec_helper.rb +92 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c161257669d03d28242c5a446035de4b2053fc75
|
4
|
+
data.tar.gz: ffaced6c4f32e3a1e80e2b3cca6b707aa0881f19
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 14d97e90b02a189ad3b845853e6541396180f2257edbb3e22488bd4e2546fc8ef6520b703c20eb8e58acece20ec408705e0f348a4cd7ff60c80b9c2ac0b0ba1f
|
7
|
+
data.tar.gz: 6712fc03b8565754d297f854ec55bc765aae826e677355cb552681f11bb2192bec1cd0785307c470b01965ee1810df448e6812324ed0023bde7c3413f0a38c0b
|
data/Gemfile
ADDED
data/History.txt
ADDED
data/README.md
ADDED
File without changes
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
4
|
+
|
5
|
+
require 'bundler'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'rubygems/package_task'
|
8
|
+
|
9
|
+
require './lib/arel-helpers'
|
10
|
+
|
11
|
+
Bundler::GemHelper.install_tasks
|
12
|
+
|
13
|
+
task :default => :spec
|
14
|
+
|
15
|
+
desc 'Run specs'
|
16
|
+
RSpec::Core::RakeTask.new do |t|
|
17
|
+
t.pattern = './spec/**/*_spec.rb'
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
require 'arel-helpers/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "arel-helpers"
|
6
|
+
s.version = ::ArelHelpers::VERSION
|
7
|
+
s.authors = ["Cameron Dutro"]
|
8
|
+
s.email = ["camertron@gmail.com"]
|
9
|
+
s.homepage = "http://github.com/camertron"
|
10
|
+
|
11
|
+
s.description = s.summary = "Useful tools to help construct database queries with ActiveRecord and Arel."
|
12
|
+
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.has_rdoc = true
|
15
|
+
|
16
|
+
s.add_dependency 'activerecord', '~> 3.0'
|
17
|
+
|
18
|
+
s.require_path = 'lib'
|
19
|
+
s.files = Dir["{lib,spec}/**/*", "Gemfile", "History.txt", "README.md", "Rakefile", "arel-helpers.gemspec"]
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module ArelHelpers
|
4
|
+
module JoinAssociation
|
5
|
+
|
6
|
+
# activerecord uses JoinDependency to automagically generate inner join statements for
|
7
|
+
# any type of association (belongs_to, has_many, and has_and_belongs_to_many).
|
8
|
+
# For example, for HABTM associations, two join statements are required.
|
9
|
+
# This method encapsulates that functionality and returns a SelectManager for chaining.
|
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)
|
12
|
+
associations = association.is_a?(Array) ? association : [association]
|
13
|
+
join_dependency = ActiveRecord::Associations::JoinDependency.new(table, associations, [])
|
14
|
+
manager = Arel::SelectManager.new(table)
|
15
|
+
|
16
|
+
join_dependency.join_associations.each do |assoc|
|
17
|
+
assoc.join_type = join_type
|
18
|
+
assoc.join_to(manager)
|
19
|
+
end
|
20
|
+
|
21
|
+
manager.join_sources.map do |assoc|
|
22
|
+
if block_given?
|
23
|
+
# yield |assoc_name, join_conditions|
|
24
|
+
right = yield assoc.left.name.to_sym, assoc.right
|
25
|
+
assoc.class.new(assoc.left, right)
|
26
|
+
else
|
27
|
+
assoc
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
data/lib/arel-helpers.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe ArelHelpers::ArelTable do
|
6
|
+
it "should add the [] function to the model and allow attribute access" do
|
7
|
+
Post[:id].tap do |post_id|
|
8
|
+
post_id.should be_a(Arel::Attribute)
|
9
|
+
post_id.name.should == :id
|
10
|
+
post_id.relation.name.should == "posts"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe ArelHelpers::JoinAssociation do
|
6
|
+
include ArelHelpers::JoinAssociation
|
7
|
+
|
8
|
+
describe "#join_association" do
|
9
|
+
it "should work for a directly associated model" do
|
10
|
+
Post.joins(join_association(Post, :comments)).to_sql.should ==
|
11
|
+
'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should work with an outer join" do
|
15
|
+
Post.joins(join_association(Post, :comments, Arel::OuterJoin)).to_sql.should ==
|
16
|
+
'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should allow adding additional join conditions" do
|
20
|
+
Post.joins(join_association(Post, :comments) do |assoc_name, join_conditions|
|
21
|
+
join_conditions.and(Comment[:id].eq(10))
|
22
|
+
end).to_sql.should ==
|
23
|
+
'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" AND "comments"."id" = 10'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should work for two models, one directly associated and the other indirectly" do
|
27
|
+
Post
|
28
|
+
.joins(join_association(Post, :comments))
|
29
|
+
.joins(join_association(Comment, :commenter))
|
30
|
+
.to_sql.should ==
|
31
|
+
'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" INNER JOIN "commenters" ON "commenters"."comment_id" = "comments"."id"'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should be able to handle multiple associations" do
|
35
|
+
Post.joins(join_association(Post, [:comments, :favorites])).to_sql.should ==
|
36
|
+
'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" INNER JOIN "favorites" ON "favorites"."post_id" = "posts"."id"'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should yield once for each association" do
|
40
|
+
Post.joins(join_association(Post, [:comments, :favorites]) do |assoc_name, join_conditions|
|
41
|
+
case assoc_name
|
42
|
+
when :favorites
|
43
|
+
join_conditions.or(Favorite[:amount].eq("lots"))
|
44
|
+
when :comments
|
45
|
+
join_conditions.and(Comment[:text].eq("Awesome post!"))
|
46
|
+
end
|
47
|
+
end).to_sql.should ==
|
48
|
+
'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" AND "comments"."text" = \'Awesome post!\' INNER JOIN "favorites" (ON "favorites"."post_id" = "posts"."id" OR "favorites"."amount" = \'lots\')'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'arel-helpers'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'pry-nav'
|
7
|
+
|
8
|
+
def silence(&block)
|
9
|
+
original_stdout = $stdout
|
10
|
+
$stdout = StringIO.new
|
11
|
+
begin
|
12
|
+
yield
|
13
|
+
ensure
|
14
|
+
$stdout = original_stdout
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Post < ActiveRecord::Base
|
19
|
+
include ArelHelpers::ArelTable
|
20
|
+
has_many :comments
|
21
|
+
has_many :favorites
|
22
|
+
end
|
23
|
+
|
24
|
+
class Comment < ActiveRecord::Base
|
25
|
+
include ArelHelpers::ArelTable
|
26
|
+
belongs_to :post
|
27
|
+
has_one :commenter
|
28
|
+
end
|
29
|
+
|
30
|
+
class Commenter < ActiveRecord::Base
|
31
|
+
include ArelHelpers::ArelTable
|
32
|
+
belongs_to :comment
|
33
|
+
end
|
34
|
+
|
35
|
+
class Favorite < ActiveRecord::Base
|
36
|
+
include ArelHelpers::ArelTable
|
37
|
+
belongs_to :post
|
38
|
+
end
|
39
|
+
|
40
|
+
class CreatePostsTable < ActiveRecord::Migration
|
41
|
+
def change
|
42
|
+
create_table :posts
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class CreateCommentsTable < ActiveRecord::Migration
|
47
|
+
def change
|
48
|
+
create_table :comments do |t|
|
49
|
+
t.references :post
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class CreateCommentersTable < ActiveRecord::Migration
|
55
|
+
def change
|
56
|
+
create_table :commenters do |t|
|
57
|
+
t.references :comment
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class CreateFavoritesTable < ActiveRecord::Migration
|
63
|
+
def change
|
64
|
+
create_table :favorites do |t|
|
65
|
+
t.references :post
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
RSpec.configure do |config|
|
71
|
+
config.mock_with :rr
|
72
|
+
|
73
|
+
db_dir = File.join(File.dirname(File.dirname(__FILE__)), "tmp")
|
74
|
+
db_file = File.join(db_dir, "test.sqlite3")
|
75
|
+
|
76
|
+
config.before(:each) do
|
77
|
+
File.unlink(db_file) if File.exist?(db_file)
|
78
|
+
FileUtils.mkdir_p(db_dir)
|
79
|
+
|
80
|
+
ActiveRecord::Base.establish_connection(
|
81
|
+
:adapter => "sqlite3",
|
82
|
+
:database => db_file
|
83
|
+
)
|
84
|
+
|
85
|
+
silence do
|
86
|
+
CreatePostsTable.new.change
|
87
|
+
CreateCommentsTable.new.change
|
88
|
+
CreateCommentersTable.new.change
|
89
|
+
CreateFavoritesTable.new.change
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: arel-helpers
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cameron Dutro
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
description: Useful tools to help construct database queries with ActiveRecord and
|
28
|
+
Arel.
|
29
|
+
email:
|
30
|
+
- camertron@gmail.com
|
31
|
+
executables: []
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- Gemfile
|
36
|
+
- History.txt
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- arel-helpers.gemspec
|
40
|
+
- lib/arel-helpers.rb
|
41
|
+
- lib/arel-helpers/arel_table.rb
|
42
|
+
- lib/arel-helpers/join_association.rb
|
43
|
+
- lib/arel-helpers/version.rb
|
44
|
+
- spec/arel_table_spec.rb
|
45
|
+
- spec/join_association_spec.rb
|
46
|
+
- spec/spec_helper.rb
|
47
|
+
homepage: http://github.com/camertron
|
48
|
+
licenses: []
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.2.2
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: Useful tools to help construct database queries with ActiveRecord and Arel.
|
70
|
+
test_files: []
|