mintdigital-minty_scopes 0.9.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.
data/README.mkdn ADDED
@@ -0,0 +1,69 @@
1
+ What
2
+ ====
3
+
4
+ A collection of handy `named_scope`s that you should be able to use in just about any model.
5
+
6
+ Why
7
+ ===
8
+
9
+ Named scopes turn ugly finders into pretty ones.
10
+
11
+ Howto
12
+ =====
13
+
14
+ Specify the gem dependency in your `environment.rb`:
15
+
16
+ config.gem 'mintdigital-minty_scopes',
17
+ :lib => 'minty_scopes',
18
+ :source => "http://gems.github.com"
19
+
20
+ Then install and unpack the gem:
21
+
22
+ rake gems:install
23
+ rake gems:unpack
24
+
25
+ In any model, you can get the scopes by extending the module:
26
+
27
+ class Post < ActiveRecord::Base
28
+ extend MintyScopes
29
+ end
30
+
31
+ Scopes
32
+ ======
33
+
34
+ Scopes are grouped into modules by functionality. If you only want some scopes, feel free to extend only the modules you want: `extend MintyScopes::Timestamps`
35
+
36
+ ### Associations ###
37
+
38
+ with(:comments) #=> :joins => :comments, :group => 'posts.id' (only posts with comments)
39
+ without(:comments) #=> :joins => 'LEFT JOIN comments ON posts.id = comments.post_id',
40
+ # :conditions => {'comments.id' => nil}
41
+ including(:comments) #=> :include => [:comments]
42
+
43
+ ### Except ###
44
+
45
+ except(post) #=> [ 'posts.id NOT IN (?)', post ]
46
+ except(post, post) #=> [ 'posts.id NOT IN (?)', [post, post] ]
47
+ except(post_collection) #=> [ 'posts.id NOT IN (?)', post_collection ]
48
+
49
+ ### Order ###
50
+
51
+ newest #=> { :order => 'created_at DESC', :limit => per_page || limit }
52
+ newest(20) #=> { :order => 'created_at DESC', :limit => 20 }
53
+ oldest #=> { :order => 'created_at ASC', :limit => per_page || limit }
54
+ oldest(20) #=> { :order => 'created_at ASC', :limit => 20 }
55
+
56
+ ### Timestamps ###
57
+
58
+ created_on(date) #=> :created_at => (date.beginning_of_day..date.end_of_day)
59
+ modified_on(date) #=> :modified_at => (date.beginning_of_day..date.end_of_day)
60
+
61
+ Thanks
62
+ ======
63
+
64
+ Big thanks to Ryan Daigle for his [utility_scopes](http://github.com/yfactorial/utility_scope) plugin, the inspiration for this project.
65
+
66
+ License
67
+ =======
68
+
69
+ © 2008 Dean Strelau, Mint Digital. All Rights Reserved.
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/gempackagetask'
4
+ require 'lib/minty_scopes/version'
5
+
6
+ desc 'Default: Run Tests'
7
+ task :default => ['test']
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = "minty_scopes"
11
+ s.version = MintyScopes::VERSION
12
+ s.summary = "Useful, reusable named_scopes for ActiveRecord."
13
+ s.homepage = "https://github.com/mintdigital/minty_scopes"
14
+
15
+ s.files = FileList["[A-Z]*", "{lib,test}/**/*"]
16
+
17
+ s.has_rdoc = false
18
+ s.extra_rdoc_files = ["README.mkdn", 'Rakefile']
19
+ s.rdoc_options = ["--line-numbers", "--inline-source",
20
+ "--main", "README.txt"]
21
+
22
+ s.authors = ["Dean Strelau"]
23
+ s.email = "dean@mintdigital.com"
24
+
25
+ s.add_dependency "activerecord", ">= 2.1.0"
26
+ s.add_dependency "activesupport", ">= 2.1.0"
27
+ end
28
+
29
+ Rake::GemPackageTask.new spec do |pkg|
30
+ pkg.need_tar = true
31
+ pkg.need_zip = true
32
+ end
33
+
34
+ desc "Generate a gemspec file for GitHub"
35
+ task :gemspec do
36
+ File.open("#{spec.name}.gemspec", 'w') do |f|
37
+ f.write spec.to_ruby
38
+ end
39
+ end
@@ -0,0 +1,15 @@
1
+ require 'minty_scopes/version'
2
+
3
+ require 'minty_scopes/associations'
4
+ require 'minty_scopes/except'
5
+ require 'minty_scopes/order'
6
+ require 'minty_scopes/timestamps'
7
+
8
+ module MintyScopes
9
+ def self.extended(within)
10
+ within.extend MintyScopes::Associations
11
+ within.extend MintyScopes::Except
12
+ within.extend MintyScopes::Order
13
+ within.extend MintyScopes::Timestamps
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ module MintyScopes
2
+ module Associations
3
+
4
+ def self.extended(within)
5
+ within.class_eval do
6
+ # Only show items that have at least one of the associated items
7
+ # Meant for has_many associations
8
+ # Post.with(:comments)
9
+ named_scope :with, lambda { |assoc|
10
+ raise "The 'with' named_scope expects a non-nil argument." if assoc.nil?
11
+ { :joins => assoc.to_sym, :group => "#{quoted_table_name}.id" }
12
+ }
13
+
14
+ named_scope :without, lambda {|assoc|
15
+ raise "The 'without' named_scope expects a non-nil argument." if assoc.nil?
16
+ { :joins => "LEFT JOIN #{assoc.to_s} "+
17
+ "ON #{quoted_table_name}.id = #{assoc.to_s}.#{quoted_table_name.singularize}_id",
18
+ :conditions => {"#{assoc}.id" => nil} }
19
+ }
20
+ named_scope :including, lambda {|*assocs|
21
+ { :include => assocs.flatten }
22
+ }
23
+
24
+ end
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,17 @@
1
+ module MintyScopes
2
+ module Except
3
+
4
+ def self.extended(within)
5
+ within.class_eval do
6
+ # Allow easy rejection of items.
7
+ # Can take an a single id or ActiveRecord object, or an array of them
8
+ named_scope :except, lambda { |*args|
9
+ args.flatten!
10
+ raise "The 'except' named_scope expects no nil values." unless args.all?
11
+ { :conditions => ["#{quoted_table_name}.#{primary_key} NOT IN (?)", args] }
12
+ }
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module MintyScopes
2
+ module Order
3
+
4
+ def self.extended(within)
5
+ within.class_eval do
6
+ # Get only the newest items. Limit by given parameter.
7
+ # Default to per_page if will_paginate is installed or 10
8
+ named_scope :newest, lambda { |*limit| {
9
+ :order => "#{quoted_table_name}.created_at DESC",
10
+ :limit => limit.empty? ? (per_page rescue 10) : limit.first
11
+ } }
12
+
13
+ # Get only the oldest items. Limit by given parameter.
14
+ # Default to per_page if will_paginate is installed or 10
15
+ named_scope :oldest, lambda { |*limit| {
16
+ :order => "#{quoted_table_name}.created_at ASC",
17
+ :limit => limit.empty? ? (per_page rescue 10) : limit.first
18
+ } }
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module MintyScopes
2
+ module Timestamps
3
+
4
+ def self.extended(within)
5
+ within.class_eval do
6
+ # Allow filtering by day of created_on
7
+ # Argument must be a Date, Time, or DateTime
8
+ named_scope :created_on, lambda { |date|
9
+ raise "The 'created_on' named_scope expects a Date, Time or DateTime object" unless date.respond_to? :end_of_day
10
+ { :conditions => {:created_at => (date.beginning_of_day..date.end_of_day)} }
11
+ }
12
+
13
+ # Allow filtering by day of modified_on
14
+ # Argument must be a Date, Time, or DateTime
15
+ named_scope :modified_on, lambda { |date|
16
+ raise "The 'modified_on' named_scope expects a Date, Time or DateTime object" unless date.respond_to? :end_of_day
17
+ { :conditions => {:modified_on => (date.beginning_of_day..date.end_of_day)} }
18
+ }
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module MintyScopes
2
+ VERSION = '0.9.0'
3
+ end
@@ -0,0 +1,19 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'minty_scopes'
3
+
4
+ require 'test/unit'
5
+ require 'rubygems'
6
+ require 'shoulda'
7
+ require 'activerecord'
8
+ require 'activesupport'
9
+
10
+ class Post < ActiveRecord::Base
11
+ def self.quoted_table_name; 'posts'; end
12
+ def self.primary_key; 'id'; end
13
+ extend MintyScopes
14
+ end
15
+
16
+ class PaginatedPost < Post
17
+ def self.per_page; 30; end
18
+ extend MintyScopes
19
+ end
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class AssociationsTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "with" do
6
+ should "complain if passed nil" do
7
+ assert_raise(RuntimeError) { Post.with(nil).proxy_options }
8
+ end
9
+
10
+ should "return all objects with associated items" do
11
+ assert_equal( { :joins => :comments, :group => 'posts.id' },
12
+ Post.with(:comments).proxy_options )
13
+ end
14
+ end
15
+
16
+ context "without" do
17
+ should "complain if passed nil" do
18
+ assert_raise(RuntimeError) { Post.with(nil).proxy_options }
19
+ end
20
+
21
+ should "return all objects without associated items" do
22
+ assert_equal( { :joins => "LEFT JOIN comments ON posts.id = comments.post_id",
23
+ :conditions => {"comments.id" => nil} },
24
+ Post.without(:comments).proxy_options )
25
+ end
26
+ end
27
+
28
+ context "including" do
29
+ should "return objects with given include" do
30
+ assert_equal( { :include => [:comments] },
31
+ Post.including(:comments).proxy_options )
32
+ end
33
+
34
+ should "return objects with all of given includes" do
35
+ assert_equal( { :include => [:comments, {:author => :avator}] },
36
+ Post.including(:comments, {:author => :avator}).proxy_options )
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ExceptTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "except" do
6
+ should "complain if passed nil" do
7
+ assert_raise(RuntimeError){ Post.except(nil).proxy_options }
8
+ end
9
+
10
+ should "complain if passed an array with nil" do
11
+ assert_raise(RuntimeError) { Post.except([99,nil,101]).proxy_options }
12
+ end
13
+
14
+ should "return all but the given object" do
15
+ item = 123
16
+ assert_equal( { :conditions => ["posts.id NOT IN (?)", [item]] },
17
+ Post.except(item).proxy_options )
18
+ end
19
+
20
+ should "return all but the items in the given list" do
21
+ list = [123, 456, 7]
22
+ assert_equal( { :conditions => ["posts.id NOT IN (?)", list] },
23
+ Post.except(list).proxy_options )
24
+ end
25
+
26
+ should "return all but the given items" do
27
+ maple, oak = 42, 24
28
+ assert_equal( { :conditions => ["posts.id NOT IN (?)", [maple, oak]] },
29
+ Post.except(maple, oak).proxy_options )
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,49 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class OrderTest < Test::Unit::TestCase # :nodoc:
4
+
5
+ context "newest" do
6
+ should "return most recent items" do
7
+ assert Post.newest.proxy_options[:order] = 'posts.created_at DESC'
8
+ end
9
+
10
+ should "default to 10 items" do
11
+ assert_equal 10, Post.newest.proxy_options[:limit]
12
+ end
13
+
14
+ should "use the given limit" do
15
+ assert_equal 20, Post.newest(20).proxy_options[:limit]
16
+ end
17
+
18
+ should "default to per_page if it exists" do
19
+ assert_equal 30, PaginatedPost.newest.proxy_options[:limit]
20
+ end
21
+
22
+ should "use the given limit over per_page" do
23
+ assert_equal 15, PaginatedPost.newest(15).proxy_options[:limit]
24
+ end
25
+ end
26
+
27
+ context "oldest" do
28
+ should "return oldest items" do
29
+ assert Post.oldest.proxy_options[:order] = 'posts.created_at ASC'
30
+ end
31
+
32
+ should "default to 10 items" do
33
+ assert_equal 10, Post.oldest.proxy_options[:limit]
34
+ end
35
+
36
+ should "use the given limit" do
37
+ assert_equal 20, Post.oldest(20).proxy_options[:limit]
38
+ end
39
+
40
+ should "default to per_page if it exists" do
41
+ assert_equal 30, PaginatedPost.oldest.proxy_options[:limit]
42
+ end
43
+
44
+ should "use the given limit over per_page" do
45
+ assert_equal 15, PaginatedPost.oldest(15).proxy_options[:limit]
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,32 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class TimestampsTest < Test::Unit::TestCase # :nodoc:
4
+ def setup
5
+ @today = Date.today
6
+ end
7
+
8
+ context "created_on" do
9
+ should "complain if passed a non date or time" do
10
+ assert_raise(RuntimeError){ Post.created_on(nil).proxy_options }
11
+ end
12
+
13
+ should "return all objects created on the given date" do
14
+ assert_equal({:conditions =>
15
+ { :created_at => (@today.beginning_of_day..@today.end_of_day) }
16
+ }, Post.created_on(@today).proxy_options)
17
+ end
18
+ end
19
+
20
+ context "modified_on" do
21
+ should "complain if passed a non date or time" do
22
+ assert_raise(RuntimeError){ Post.modified_on(nil).proxy_options }
23
+ end
24
+
25
+ should "return all objects modified on the given date" do
26
+ assert_equal({:conditions =>
27
+ { :modified_on => (@today.beginning_of_day..@today.end_of_day) }
28
+ }, Post.modified_on(@today).proxy_options)
29
+ end
30
+ end
31
+
32
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mintdigital-minty_scopes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - Dean Strelau
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-16 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activerecord
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.1.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.1.0
34
+ version:
35
+ description:
36
+ email: dean@mintdigital.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.mkdn
43
+ - Rakefile
44
+ files:
45
+ - Rakefile
46
+ - README.mkdn
47
+ - lib/minty_scopes
48
+ - lib/minty_scopes/associations.rb
49
+ - lib/minty_scopes/except.rb
50
+ - lib/minty_scopes/order.rb
51
+ - lib/minty_scopes/timestamps.rb
52
+ - lib/minty_scopes/version.rb
53
+ - lib/minty_scopes.rb
54
+ - test/test_helper.rb
55
+ - test/units
56
+ - test/units/associations_test.rb
57
+ - test/units/except_test.rb
58
+ - test/units/order_test.rb
59
+ - test/units/timestamps_test.rb
60
+ has_rdoc: false
61
+ homepage: https://github.com/mintdigital/minty_scopes
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --line-numbers
65
+ - --inline-source
66
+ - --main
67
+ - README.txt
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.2.0
86
+ signing_key:
87
+ specification_version: 2
88
+ summary: Useful, reusable named_scopes for ActiveRecord.
89
+ test_files: []
90
+