scope-builder 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ *0.1.2* (August 28th, 2008)
2
+
3
+ * scope_builder can be called on association proxy
4
+
5
+ *0.1.1* (June 26th, 2008)
6
+
7
+ * scope_builder can be called on any Scope
8
+
9
+ *0.1.0* (June 26th, 2008)
10
+
11
+ * initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Ryan Bates
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ CHANGELOG
2
+ lib/scope_builder/builder.rb
3
+ lib/scope_builder/model_additions.rb
4
+ lib/scope_builder.rb
5
+ LICENSE
6
+ Manifest
7
+ README
8
+ scope-builder.gemspec
9
+ spec/models/category.rb
10
+ spec/models/product.rb
11
+ spec/scope_builder/builder_spec.rb
12
+ spec/spec_helper.rb
13
+ tasks/deployment.rake
14
+ tasks/spec.rake
@@ -0,0 +1,56 @@
1
+ = Scope Builder
2
+
3
+ Build up named scopes conditionally.
4
+
5
+
6
+ == Install
7
+
8
+ First specify it in your Rails config.
9
+
10
+ config.gem 'ryanb-scope-builder', :lib => 'scope_builder', :source => 'http://gems.github.com'
11
+
12
+ And then install it.
13
+
14
+ rake gems:install
15
+
16
+ Rails 2.1 or later required.
17
+
18
+
19
+ == Usage
20
+
21
+ This gem adds the scope_builder method to all Active Record models. A
22
+ builder behaves exactly like any other named scope except that calling
23
+ other named scopes on it will alter the builder itself rather than
24
+ returning a new named scope.
25
+
26
+ builder = Product.scope_builder
27
+ builder.released.visible # call a couple named scopes to change builder
28
+ builder.cheap if only_show_cheap_products? # build scopes conditionally
29
+
30
+ The scope_builder method can also take a block which will return the
31
+ builder. This is useful when you are using the builder in a model
32
+ search method.
33
+
34
+ # in product model
35
+ def self.search(options)
36
+ scope_builder do |builder|
37
+ builder.released.visible
38
+ builder.cheap if options[:cheap]
39
+ end
40
+ end
41
+
42
+ The scope_builder method can also be called on an existing scope.
43
+
44
+ products = Product.released.visible
45
+ builder = products.scope_builder
46
+ builder.cheap if only_show_cheap_products?
47
+
48
+
49
+ == Development
50
+
51
+ This project can be found on github at the following URL.
52
+
53
+ http://github.com/ryanb/scope-builder/
54
+
55
+ If you would like to contribute to this project, please fork the
56
+ repository and send me a pull request.
@@ -0,0 +1,3 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+ require 'scope_builder/model_additions'
3
+ require 'scope_builder/builder'
@@ -0,0 +1,25 @@
1
+ module ScopeBuilder
2
+ class Builder
3
+ def initialize(proxy_scope)
4
+ @proxy_scope = proxy_scope
5
+ end
6
+
7
+ def method_missing(method, *args, &block)
8
+ result = @proxy_scope.send(method, *args, &block)
9
+ if result.class == ActiveRecord::NamedScope::Scope
10
+ @proxy_scope = result
11
+ self
12
+ else
13
+ result
14
+ end
15
+ end
16
+
17
+ def respond_to?(method)
18
+ super || @proxy_scope.respond_to?(method)
19
+ end
20
+
21
+ def inspect
22
+ sprintf("#<%s:%#0x>", self.class.to_s, self.object_id)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ module ScopeBuilder
2
+ module ModelAdditions
3
+ def scope_builder
4
+ builder = Builder.new(scoped({}))
5
+ yield(builder) if block_given?
6
+ builder
7
+ end
8
+ end
9
+ end
10
+
11
+ class ActiveRecord::Base
12
+ extend ScopeBuilder::ModelAdditions
13
+ end
14
+
15
+ class ActiveRecord::Associations::AssociationProxy
16
+ include ScopeBuilder::ModelAdditions
17
+ end
18
+
19
+ class ActiveRecord::NamedScope::Scope
20
+ include ScopeBuilder::ModelAdditions
21
+ end
@@ -0,0 +1,51 @@
1
+
2
+ # Gem::Specification for Scope-builder-0.1.2
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{scope-builder}
7
+ s.version = "0.1.2"
8
+
9
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
+ s.authors = ["Ryan Bates"]
11
+ s.date = %q{2008-08-28}
12
+ s.description = %q{Build up named scopes conditionally.}
13
+ s.email = %q{ryan (at) railscasts (dot) com}
14
+ s.extra_rdoc_files = ["CHANGELOG", "lib/scope_builder/builder.rb", "lib/scope_builder/model_additions.rb", "lib/scope_builder.rb", "LICENSE", "README.rdoc", "tasks/deployment.rake", "tasks/spec.rake"]
15
+ s.files = ["CHANGELOG", "lib/scope_builder/builder.rb", "lib/scope_builder/model_additions.rb", "lib/scope_builder.rb", "LICENSE", "Manifest", "README.rdoc", "scope-builder.gemspec", "spec/models/category.rb", "spec/models/product.rb", "spec/scope_builder/builder_spec.rb", "spec/spec_helper.rb", "tasks/deployment.rake", "tasks/spec.rake"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/ryanb/scope-builder}
18
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Scope-builder", "--main", "README.rdoc"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{scope-builder}
21
+ s.rubygems_version = %q{1.2.0}
22
+ s.summary = %q{Build up named scopes conditionally.}
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 2
27
+
28
+ if current_version >= 3 then
29
+ else
30
+ end
31
+ else
32
+ end
33
+ end
34
+
35
+
36
+ # # Original Rakefile source (requires the Echoe gem):
37
+ #
38
+ # require 'rubygems'
39
+ # require 'rake'
40
+ # require 'echoe'
41
+ #
42
+ # Echoe.new('scope-builder', '0.1.2') do |p|
43
+ # p.summary = "Build up named scopes conditionally."
44
+ # p.description = "Build up named scopes conditionally."
45
+ # p.url = "http://github.com/ryanb/scope-builder"
46
+ # p.author = 'Ryan Bates'
47
+ # p.email = "ryan (at) railscasts (dot) com"
48
+ # p.ignore_pattern = ["script/*", "**/*.sqlite3"]
49
+ # end
50
+ #
51
+ # Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
@@ -0,0 +1,15 @@
1
+ class Category < ActiveRecord::Base
2
+ has_many :products
3
+ end
4
+
5
+ class CreateCategories < ActiveRecord::Migration
6
+ def self.up
7
+ create_table :categories do |t|
8
+ t.string :name
9
+ end
10
+ end
11
+
12
+ def self.down
13
+ drop_table :categories
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ class Product < ActiveRecord::Base
2
+ named_scope :released, :conditions => ['released=?', true]
3
+ belongs_to :category
4
+ end
5
+
6
+ class CreateProducts < ActiveRecord::Migration
7
+ def self.up
8
+ create_table :products do |t|
9
+ t.string :name
10
+ t.boolean :released
11
+ t.integer :category_id
12
+ end
13
+ end
14
+
15
+ def self.down
16
+ drop_table :products
17
+ end
18
+ end
@@ -0,0 +1,73 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe ScopeBuilder::Builder do
4
+ before(:each) do
5
+ Product.delete_all
6
+ Product.create!(:name => 'a', :released => true)
7
+ Product.create!(:name => 'b', :released => false)
8
+ Product.create!(:name => 'c', :released => true)
9
+
10
+ @builder = Product.scope_builder
11
+ end
12
+
13
+ it "should start with empty proxy options" do
14
+ @builder.proxy_options.should == {}
15
+ end
16
+
17
+ it "should allow named scopes to be called through it" do
18
+ @builder.released.proxy_options.should == Product.released.proxy_options
19
+ end
20
+
21
+ it "should remember scope calls" do
22
+ @builder.released
23
+ @builder.proxy_options.should == Product.released.proxy_options
24
+ end
25
+
26
+ it "should build up scopes" do
27
+ @builder.released.scoped(:limit => 1)
28
+ @builder.scoped(:offset => 1)
29
+ @builder.all.should == Product.released.scoped(:limit => 1, :offset => 1).all
30
+ end
31
+
32
+ it "should enumerate like an array" do
33
+ products = Product.find(:all)
34
+ @builder.each_with_index do |product, index|
35
+ product.should == products[index]
36
+ end
37
+ end
38
+
39
+ it "should not include instance variables on inspect so it doesn't load proxy" do
40
+ @builder.inspect.should_not include('proxy_scope')
41
+ end
42
+
43
+ it "should respond to enumerable methods like each_with_index" do
44
+ @builder.should respond_to(:each_with_index)
45
+ end
46
+
47
+ it "should be able to build up scope in block" do
48
+ Product.scope_builder { |b| b.released }.all.should == Product.released.all
49
+ end
50
+
51
+ it "should be able to call scope builder on an existing scope" do
52
+ builder = Product.released.scope_builder
53
+ builder.all.should == Product.released.all
54
+ end
55
+
56
+ describe "products in category" do
57
+ before(:each) do
58
+ Category.delete_all
59
+ @category = Category.create!(:products => Product.find_all_by_name(['a', 'b']))
60
+ end
61
+
62
+ it "should work on named scope through association" do
63
+ builder = @category.products.released.scope_builder
64
+ builder.all.should == @category.products.released.all
65
+ end
66
+
67
+ it "should work directly on assocation" do
68
+ builder = @category.products.scope_builder
69
+ builder.released
70
+ builder.all.should == @category.products.released.all
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'active_support'
4
+ require 'active_record'
5
+ require File.dirname(__FILE__) + '/../lib/scope_builder.rb'
6
+
7
+ # setup database adapter
8
+ ActiveRecord::Base.establish_connection({
9
+ :adapter => "sqlite3",
10
+ :dbfile => File.dirname(__FILE__) + "/test.sqlite3"
11
+ })
12
+
13
+ # load models
14
+ # there's probably a better way to handle this
15
+ require File.dirname(__FILE__) + '/models/category.rb'
16
+ require File.dirname(__FILE__) + '/models/product.rb'
17
+ CreateCategories.migrate(:up) unless Category.table_exists?
18
+ CreateProducts.migrate(:up) unless Product.table_exists?
19
+
20
+ Spec::Runner.configure do |config|
21
+ config.mock_with :mocha
22
+ end
@@ -0,0 +1,2 @@
1
+ desc "Build the manifest and gemspec files."
2
+ task :build => [:build_manifest, :build_gemspec]
@@ -0,0 +1,9 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ spec_files = Rake::FileList["spec/**/*_spec.rb"]
4
+
5
+ desc "Run specs"
6
+ Spec::Rake::SpecTask.new do |t|
7
+ t.spec_files = spec_files
8
+ t.spec_opts = ["-c"]
9
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scope-builder
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 2
9
+ version: 0.1.2
10
+ platform: ruby
11
+ authors:
12
+ - Ryan Bates
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2008-08-28 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Build up named scopes conditionally.
22
+ email: ryan (at) railscasts (dot) com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - CHANGELOG
29
+ - lib/scope_builder/builder.rb
30
+ - lib/scope_builder/model_additions.rb
31
+ - lib/scope_builder.rb
32
+ - LICENSE
33
+ - README.rdoc
34
+ - tasks/deployment.rake
35
+ - tasks/spec.rake
36
+ files:
37
+ - CHANGELOG
38
+ - lib/scope_builder/builder.rb
39
+ - lib/scope_builder/model_additions.rb
40
+ - lib/scope_builder.rb
41
+ - LICENSE
42
+ - Manifest
43
+ - README.rdoc
44
+ - scope-builder.gemspec
45
+ - spec/models/category.rb
46
+ - spec/models/product.rb
47
+ - spec/scope_builder/builder_spec.rb
48
+ - spec/spec_helper.rb
49
+ - tasks/deployment.rake
50
+ - tasks/spec.rake
51
+ has_rdoc: true
52
+ homepage: http://github.com/ryanb/scope-builder
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --line-numbers
58
+ - --inline-source
59
+ - --title
60
+ - Scope-builder
61
+ - --main
62
+ - README.rdoc
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ requirements: []
80
+
81
+ rubyforge_project: scope-builder
82
+ rubygems_version: 1.3.6
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: Build up named scopes conditionally.
86
+ test_files: []
87
+