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 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
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'pry-nav'
7
+ gem 'rake'
8
+ end
9
+
10
+ group :test do
11
+ gem 'rspec', '~> 2.11.0'
12
+ gem 'rr', '~> 1.0.4'
13
+ gem 'sqlite3'
14
+ end
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 1.0.0
2
+
3
+ * Birthday! Includes join_association and arel_table helpers.
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,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module ArelHelpers
4
+ module ArelTable
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+
10
+ def [](name)
11
+ arel_table[name]
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ 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
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ module ArelHelpers
4
+ VERSION = "1.0.0"
5
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'active_record'
4
+
5
+ module ArelHelpers
6
+ autoload :JoinAssociation, "arel-helpers/join_association"
7
+ autoload :ArelTable, "arel-helpers/arel_table"
8
+ end
@@ -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
@@ -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: []