pacecar 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -8,6 +8,17 @@ To get all Pacecar functionality, you need to "include Pacecar" in your class.
8
8
 
9
9
  To get some subset (for example, only the state functionality), you can do something like "include Pacecar::State" to get only the module(s) you want.
10
10
 
11
+ == Installation
12
+
13
+ For rails 3, just include in your Gemfile
14
+
15
+ gem 'pacecar'
16
+
17
+ For prior rails versions, there is a rails2 branch to use:
18
+
19
+ gem 'pacecar', :git => 'git://github.com/thoughtbot/pacecar.git', :branch => 'rails2'
20
+
21
+
11
22
  == Usage
12
23
 
13
24
  Assuming a database schema...
@@ -183,6 +194,15 @@ Query methods on instances to check state...
183
194
  Post.first.publication_state_draft?
184
195
  Post.last.post_type_not_open?
185
196
 
197
+ = Numeric columns
198
+
199
+ Records which are greater than or less than a certain value...
200
+
201
+ User.age_greater_than(21)
202
+ User.age_greater_than_or_equal_to(21)
203
+ User.age_less_than(21)
204
+ User.age_less_than_or_equal_to(21)
205
+
186
206
  = Limits
187
207
 
188
208
  First x records...
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pacecar
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 1.3.0
10
+ version: 1.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Jankowski
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-11 00:00:00 -04:00
18
+ date: 2010-12-04 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -29,21 +29,8 @@ extra_rdoc_files:
29
29
  - README.rdoc
30
30
  files:
31
31
  - init.rb
32
- - lib/pacecar/associations.rb
33
- - lib/pacecar/boolean.rb
34
- - lib/pacecar/datetime.rb
35
- - lib/pacecar/duration.rb
36
- - lib/pacecar/helpers.rb
37
- - lib/pacecar/limit.rb
38
- - lib/pacecar/order.rb
39
- - lib/pacecar/polymorph.rb
40
- - lib/pacecar/presence.rb
41
- - lib/pacecar/ranking.rb
42
- - lib/pacecar/search.rb
43
- - lib/pacecar/state.rb
44
- - lib/pacecar.rb
45
- - MIT-LICENSE
46
32
  - README.rdoc
33
+ - MIT-LICENSE
47
34
  has_rdoc: true
48
35
  homepage: http://github.com/thoughtbot/pacecar
49
36
  licenses: []
data/lib/pacecar.rb DELETED
@@ -1,32 +0,0 @@
1
- require 'pacecar/associations'
2
- require 'pacecar/boolean'
3
- require 'pacecar/datetime'
4
- require 'pacecar/duration'
5
- require 'pacecar/helpers'
6
- require 'pacecar/limit'
7
- require 'pacecar/order'
8
- require 'pacecar/polymorph'
9
- require 'pacecar/presence'
10
- require 'pacecar/ranking'
11
- require 'pacecar/search'
12
- require 'pacecar/state'
13
-
14
- module Pacecar
15
- def self.included(base)
16
- base.class_eval do
17
- include Pacecar::Associations
18
- include Pacecar::Boolean
19
- include Pacecar::Datetime
20
- include Pacecar::Duration
21
- include Pacecar::Limit
22
- include Pacecar::Order
23
- include Pacecar::Polymorph
24
- include Pacecar::Presence
25
- include Pacecar::Ranking
26
- include Pacecar::Search
27
- include Pacecar::State
28
- end
29
- end
30
- end
31
-
32
- ActiveRecord::Base.send :include, Pacecar::Helpers
@@ -1,39 +0,0 @@
1
- module Pacecar
2
- module Associations
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
-
9
- def has_recent_records(*names)
10
- names.each do |name|
11
- scope "recent_#{name}_since".to_sym, lambda { |since|
12
- {
13
- :conditions => [conditions_for_name(name), { :since_time => since }]
14
- }
15
- }
16
- end
17
- unless names.first == names.last
18
- scope "recent_#{names.join('_or_')}_since".to_sym, lambda { |since|
19
- {
20
- :conditions => [names.collect { |name| conditions_for_name(name) }.join(' or '), { :since_time => since }]
21
- }
22
- }
23
- scope "recent_#{names.join('_and_')}_since".to_sym, lambda { |since|
24
- {
25
- :conditions => [names.collect { |name| conditions_for_name(name) }.join(' and '), { :since_time => since }]
26
- }
27
- }
28
- end
29
- end
30
-
31
- protected
32
-
33
- def conditions_for_name(name)
34
- "((select count(*) from \"#{name}\" where \"#{name}\".#{reflections[name].primary_key_name} = #{quoted_table_name}.id and \"#{name}\".created_at > :since_time) > 0)"
35
- end
36
-
37
- end
38
- end
39
- end
@@ -1,34 +0,0 @@
1
- module Pacecar
2
- module Boolean
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- base.send :define_boolean_scopes
10
- base.send :define_balance_count
11
- end
12
-
13
- protected
14
-
15
- def define_boolean_scopes
16
- boolean_column_names.each do |name|
17
- scope name.to_sym, :conditions => ["#{quoted_table_name}.#{name} = ?", true]
18
- scope "not_#{name}".to_sym, :conditions => ["#{quoted_table_name}.#{name} = ?", false]
19
- end
20
- end
21
-
22
- def define_balance_count
23
- boolean_column_names.each do |name|
24
- self.class_eval %Q{
25
- def self.#{name}_balance
26
- #{name}.count - not_#{name}.count
27
- end
28
- }
29
- end
30
- end
31
-
32
- end
33
- end
34
- end
@@ -1,68 +0,0 @@
1
- module Pacecar
2
- module Datetime
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- base.send :define_datetime_scopes
10
- end
11
-
12
- protected
13
-
14
- def define_datetime_scopes
15
- datetime_column_names.each do |name|
16
- define_before_after_scopes(name)
17
- define_past_future_scopes(name)
18
- define_inside_outside_scopes(name)
19
- define_in_date_scopes(name)
20
- end
21
- end
22
-
23
- def define_before_after_scopes(name)
24
- scope "#{name}_before".to_sym, lambda { |time|
25
- { :conditions => ["#{quoted_table_name}.#{name} <= ?", time] }
26
- }
27
- scope "#{name}_after".to_sym, lambda { |time|
28
- { :conditions => ["#{quoted_table_name}.#{name} >= ?", time] }
29
- }
30
- end
31
-
32
- def define_past_future_scopes(name)
33
- scope "#{name}_in_past", lambda {
34
- { :conditions => ["#{quoted_table_name}.#{name} <= ?", now] }
35
- }
36
- scope "#{name}_in_future", lambda {
37
- { :conditions => ["#{quoted_table_name}.#{name} >= ?", now] }
38
- }
39
- end
40
-
41
- def define_inside_outside_scopes(name)
42
- scope "#{name}_inside".to_sym, lambda { |start, stop|
43
- { :conditions => ["#{quoted_table_name}.#{name} >= ? and #{quoted_table_name}.#{name} <= ?", start, stop] }
44
- }
45
- scope "#{name}_outside".to_sym, lambda { |start, stop|
46
- { :conditions => ["#{quoted_table_name}.#{name} <= ? and #{quoted_table_name}.#{name} >= ?", start, stop] }
47
- }
48
- end
49
-
50
- def define_in_date_scopes(name)
51
- scope "#{name}_in_year".to_sym, lambda { |year|
52
- { :conditions => ["year(#{quoted_table_name}.#{name}) = ?", year] }
53
- }
54
- scope "#{name}_in_month".to_sym, lambda { |month|
55
- { :conditions => ["month(#{quoted_table_name}.#{name}) = ?", month] }
56
- }
57
- scope "#{name}_in_day".to_sym, lambda { |day|
58
- { :conditions => ["day(#{quoted_table_name}.#{name}) = ?", day] }
59
- }
60
- end
61
-
62
- def now
63
- defined?(Time.zone_default) && Time.zone_default ? Time.zone_default.now : Time.now
64
- end
65
-
66
- end
67
- end
68
- end
@@ -1,28 +0,0 @@
1
- module Pacecar
2
- module Duration
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- base.send :define_duration_scopes
10
- end
11
-
12
- protected
13
-
14
- def define_duration_scopes
15
- scope :with_duration_of, lambda { |duration, start, stop|
16
- { :conditions => ["datediff(#{quoted_table_name}.#{start}, #{quoted_table_name}.#{stop}) = ?", duration] }
17
- }
18
- scope :with_duration_over, lambda { |duration, start, stop|
19
- { :conditions => ["datediff(#{quoted_table_name}.#{start}, #{quoted_table_name}.#{stop}) > ?", duration] }
20
- }
21
- scope :with_duration_under, lambda { |duration, start, stop|
22
- { :conditions => ["datediff(#{quoted_table_name}.#{start}, #{quoted_table_name}.#{stop}) < ?", duration] }
23
- }
24
- end
25
-
26
- end
27
- end
28
- end
@@ -1,54 +0,0 @@
1
- module Pacecar
2
- module Helpers
3
-
4
- mattr_accessor :options
5
- self.options = {
6
- :state_pattern => /_(type|state)$/i,
7
- :default_limit => 10
8
- }
9
-
10
- def self.included(base)
11
- base.extend ClassMethods
12
- end
13
-
14
- module ClassMethods
15
-
16
- def safe_columns
17
- begin
18
- columns
19
- rescue ActiveRecord::StatementInvalid # If the table does not exist
20
- Array.new
21
- end
22
- end
23
-
24
- def safe_column_names
25
- safe_columns.collect(&:name)
26
- end
27
-
28
- def column_names_for_type(*types)
29
- safe_columns.select { |column| types.include? column.type }.collect(&:name)
30
- end
31
-
32
- def column_names_without_type(*types)
33
- safe_columns.select { |column| ! types.include? column.type }.collect(&:name)
34
- end
35
-
36
- def boolean_column_names
37
- column_names_for_type :boolean
38
- end
39
-
40
- def datetime_column_names
41
- column_names_for_type :datetime, :date
42
- end
43
-
44
- def text_and_string_column_names
45
- column_names_for_type :text, :string
46
- end
47
-
48
- def non_state_text_and_string_columns
49
- text_and_string_column_names.reject { |name| name =~ Pacecar::Helpers.options[:state_pattern] }
50
- end
51
-
52
- end
53
- end
54
- end
data/lib/pacecar/limit.rb DELETED
@@ -1,22 +0,0 @@
1
- module Pacecar
2
- module Limit
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- base.send :define_limit_scopes
10
- end
11
-
12
- protected
13
-
14
- def define_limit_scopes
15
- scope :limited, lambda { |*args|
16
- { :limit => args.flatten.first || (defined?(per_page) ? per_page : Pacecar::Helpers.options[:default_limit]) }
17
- }
18
- end
19
-
20
- end
21
- end
22
- end
data/lib/pacecar/order.rb DELETED
@@ -1,24 +0,0 @@
1
- module Pacecar
2
- module Order
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- base.send :define_order_scopes
10
- end
11
-
12
- protected
13
-
14
- def define_order_scopes
15
- safe_columns.collect(&:name).each do |name|
16
- scope "by_#{name}".to_sym, lambda { |*args|
17
- { :order => "#{quoted_table_name}.#{name} #{args.flatten.first || 'asc'}" }
18
- }
19
- end
20
- end
21
-
22
- end
23
- end
24
- end
@@ -1,17 +0,0 @@
1
- module Pacecar
2
- module Polymorph
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
-
9
- def has_polymorph(name)
10
- scope "for_#{name}_type".to_sym, lambda { |type|
11
- { :conditions => ["#{quoted_table_name}.#{name}_type = ?", type.to_s] }
12
- }
13
- end
14
-
15
- end
16
- end
17
- end
@@ -1,23 +0,0 @@
1
- module Pacecar
2
- module Presence
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- base.send :define_presence_scopes
10
- end
11
-
12
- protected
13
-
14
- def define_presence_scopes
15
- column_names_without_type(:boolean).each do |name|
16
- scope "#{name}_present".to_sym, :conditions => "#{quoted_table_name}.#{name} is not null"
17
- scope "#{name}_missing".to_sym, :conditions => "#{quoted_table_name}.#{name} is null"
18
- end
19
- end
20
-
21
- end
22
- end
23
- end
@@ -1,26 +0,0 @@
1
- module Pacecar
2
- module Ranking
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
-
9
- def has_ranking(association)
10
- define_ranking_scope association, :maximum, :desc
11
- define_ranking_scope association, :minimum, :asc
12
- end
13
-
14
- protected
15
-
16
- def define_ranking_scope(association, name, direction)
17
- scope "#{name}_#{association}",
18
- :joins => "inner join #{association} on #{association}.#{reflections[association].primary_key_name} = #{quoted_table_name}.#{primary_key}",
19
- :select => "#{quoted_table_name}.*, count(#{quoted_table_name}.#{primary_key}) as #{association}_count",
20
- :group => "#{association}.#{reflections[association].primary_key_name}",
21
- :order => "#{association}_count #{direction}"
22
- end
23
-
24
- end
25
- end
26
- end
@@ -1,47 +0,0 @@
1
- module Pacecar
2
- module Search
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- def self.extended(base)
9
- base.send :define_search_scopes
10
- base.send :define_basic_search_scope
11
- end
12
-
13
- protected
14
-
15
- def define_search_scopes
16
- safe_column_names.each do |name|
17
- scope "#{name}_equals".to_sym, lambda { |query|
18
- { :conditions => ["#{quoted_table_name}.#{name} = :query", { :query => query }] }
19
- }
20
- end
21
- text_and_string_column_names.each do |name|
22
- scope "#{name}_matches".to_sym, lambda { |query|
23
- { :conditions => ["#{quoted_table_name}.#{name} like :query", { :query => "%#{query}%" }] }
24
- }
25
- scope "#{name}_starts_with".to_sym, lambda { |query|
26
- { :conditions => ["#{quoted_table_name}.#{name} like :query", { :query => "#{query}%" }] }
27
- }
28
- scope "#{name}_ends_with".to_sym, lambda { |query|
29
- { :conditions => ["#{quoted_table_name}.#{name} like :query", { :query => "%#{query}" }] }
30
- }
31
- end
32
- end
33
-
34
- def define_basic_search_scope
35
- scope :search_for, lambda { |*args|
36
- opts = args.extract_options!
37
- query = args.flatten.first
38
- columns = opts[:on] || non_state_text_and_string_columns
39
- joiner = opts[:require].eql?(:all) ? 'and' : 'or'
40
- match = columns.collect { |name| "#{quoted_table_name}.#{name} like :query" }.join(" #{joiner} ")
41
- { :conditions => [match, { :query => "%#{query}%" } ] }
42
- }
43
- end
44
-
45
- end
46
- end
47
- end
data/lib/pacecar/state.rb DELETED
@@ -1,36 +0,0 @@
1
- module Pacecar
2
- module State
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
-
9
- def has_state(*names)
10
- opts = names.extract_options!
11
- names.each do |name|
12
- constant = opts[:with] || const_get(name.to_s.pluralize.upcase)
13
- constant.each do |state|
14
- scope "#{name}_#{state.downcase}".to_sym, :conditions => ["#{quoted_table_name}.#{name} = ?", state]
15
- scope "#{name}_not_#{state.downcase}".to_sym, :conditions => ["#{quoted_table_name}.#{name} <> ?", state]
16
- self.class_eval %Q{
17
- def #{name}_#{state.downcase}?
18
- #{name} == '#{state}'
19
- end
20
- def #{name}_not_#{state.downcase}?
21
- #{name} != '#{state}'
22
- end
23
- }
24
- end
25
- scope "#{name}".to_sym, lambda { |state|
26
- { :conditions => ["#{quoted_table_name}.#{name} = ?", state] }
27
- }
28
- scope "#{name}_not".to_sym, lambda { |state|
29
- { :conditions => ["#{quoted_table_name}.#{name} <> ?", state] }
30
- }
31
- end
32
- end
33
-
34
- end
35
- end
36
- end