rangetastic 0.3.2

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/MIT-License ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 Chris Herring
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,11 @@
1
+ MIT-License
2
+ Manifest
3
+ README.markdown
4
+ Rakefile
5
+ lib/rangetastic.rb
6
+ rangetastic.gemspec
7
+ spec/fixtures/models.rb
8
+ spec/fixtures/structure.sql
9
+ spec/rangetastic_spec.rb
10
+ spec/spec_helper.rb
11
+ spec/test_helper.rb
data/README.markdown ADDED
@@ -0,0 +1,40 @@
1
+ Introduction
2
+ ============
3
+ Rangetastic allows you to filter results of a named_scope call on any dates using any of a list of whitelisted fields you specify.
4
+
5
+ Configuration & Usage
6
+ =====================
7
+
8
+ To acheive this you need to install rangetastic
9
+
10
+ sudo gem install cherring-rangetastic
11
+
12
+ Then inside your environment.rb
13
+
14
+ config.gem "cherring-rangetastic", :lib => "rangetastic", :source => "http://gems.github.com"
15
+
16
+ Then in your model pass in the fields you wish to allow to be searchable using the between filter
17
+
18
+ class Order < ActiveRecord::Base
19
+ acts_as_rangetastic :fields => ["ordered_on", "fulfilled_on"]
20
+ end
21
+
22
+ You can then chain the between scope with any named_scope call you make:
23
+
24
+ Order.fulfilled.between(1.week.ago, 10.minutes.ago, "fulfilled_on")
25
+
26
+ But if you (or someone nasty!) try to use a field that is not whitelisted, it will raise ActiveRecord::StatementInvalid
27
+
28
+ Now you can also access this with the following syntax for any field ending with _on that is on the Model you are calling from like so.
29
+
30
+ Order.fulfilled.ordered_between(1.week.ago, 10.minutes.ago)
31
+
32
+ In this new version of rangetastic you can also query on _at fields. If you have an _at field such as created_at you can now
33
+
34
+ Order.fulfilled.created_between(1.week.ago, 10.minutes.ago)
35
+
36
+ However if you have an _on field and _at field the on field will take precedence over the at. If you want to access the _at field over _on field you will need to use the .between and whitelisted fields method specified first.
37
+
38
+ But if your field isn't on the Model or isn't an _on or an _at field then it will raise the standard NoMethodError.
39
+
40
+ Thanks to [spraints](http://github.com/spraints) for some inspiration.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('rangetastic', '0.3.2') do |p|
6
+ p.description = "Chain a date range to any named_scope on any date field with specified white listed fields"
7
+ p.url = "http://github.com/cherring/rangetastic"
8
+ p.author = "Chris Herring"
9
+ p.email = "chris.herring.iphone@gmail.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*"]
11
+ p.development_dependencies = []
12
+ end
13
+
14
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
@@ -0,0 +1,62 @@
1
+ module Rangetastic
2
+
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def acts_as_rangetastic(options = {:fields => []})
9
+ @fields = options[:fields]
10
+ named_scope :between, lambda{ |start_date, end_date, fieldname|
11
+ field = @fields.include?(fieldname) ? fieldname : raise(ActiveRecord::StatementInvalid)
12
+ { :conditions => ["#{field} >= ? AND #{field} <= ?", start_date, end_date] }
13
+ }
14
+ end
15
+
16
+ private
17
+ def method_missing(symbol, *args, &block)
18
+ if (field(symbol) || @fields.include?(field_to_query))
19
+ make_scope(symbol, field_to_query, *args)
20
+ else
21
+ super(symbol, *args)
22
+ end
23
+ end
24
+
25
+ def field(symbol)
26
+ if columns_hash.has_key? on_field(symbol)
27
+ @field = on_field(symbol)
28
+ elsif columns_hash.has_key? at_field(symbol)
29
+ @field = at_field(symbol)
30
+ else
31
+ @field = nil
32
+ end
33
+ end
34
+
35
+ def at_field(symbol)
36
+ "#{symbol.to_s.gsub("_between","")}_at"
37
+ end
38
+
39
+ def on_field(symbol)
40
+ "#{symbol.to_s.gsub("_between","")}_on"
41
+ end
42
+
43
+ def field_to_query
44
+ @field
45
+ end
46
+
47
+ def make_scope(scope, field, *args)
48
+ named_scope scope, lambda{ |start_date, end_date|
49
+ { :conditions => ["#{field} BETWEEN ? AND ?", start_date, end_date] }
50
+ }
51
+ call_scope(scope, *args)
52
+ end
53
+
54
+ def call_scope(scope, *args)
55
+ self.send(scope, args[0], args[1])
56
+ end
57
+ end
58
+ end
59
+
60
+ ActiveRecord::Base.class_eval do
61
+ include Rangetastic
62
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{rangetastic}
5
+ s.version = "0.3.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Chris Herring"]
9
+ s.date = %q{2009-09-20}
10
+ s.description = %q{Chain a date range to any named_scope on any date field with specified white listed fields}
11
+ s.email = %q{chris.herring.iphone@gmail.com}
12
+ s.extra_rdoc_files = ["README.markdown", "lib/rangetastic.rb"]
13
+ s.files = ["MIT-License", "Manifest", "README.markdown", "Rakefile", "lib/rangetastic.rb", "rangetastic.gemspec", "spec/fixtures/models.rb", "spec/fixtures/structure.sql", "spec/rangetastic_spec.rb", "spec/spec_helper.rb", "spec/test_helper.rb"]
14
+ s.homepage = %q{http://github.com/cherring/rangetastic}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rangetastic", "--main", "README.markdown"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{rangetastic}
18
+ s.rubygems_version = %q{1.3.4}
19
+ s.summary = %q{Chain a date range to any named_scope on any date field with specified white listed fields}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
@@ -0,0 +1,7 @@
1
+ class Order < ActiveRecord::Base
2
+
3
+ acts_as_rangetastic :fields => ["fulfilled_on","ordered_on","shipped_at"]
4
+
5
+ named_scope :fulfilled, :conditions => ["fulfilled_on is not null"]
6
+
7
+ end
@@ -0,0 +1,20 @@
1
+ DROP TABLE IF EXISTS orders;
2
+
3
+ DROP SEQUENCE IF EXISTS orders_id_seq;
4
+
5
+ CREATE SEQUENCE orders_id_seq
6
+ START WITH 1
7
+ INCREMENT BY 1
8
+ NO MAXVALUE
9
+ NO MINVALUE
10
+ CACHE 1;
11
+
12
+ CREATE TABLE orders (
13
+ id integer NOT NULL default nextval('orders_id_seq'),
14
+ ordered_on timestamp,
15
+ fulfilled_on timestamp,
16
+ shipped_at timestamp,
17
+ created_at timestamp without time zone,
18
+ updated_at timestamp without time zone
19
+ );
20
+
@@ -0,0 +1,42 @@
1
+ require 'spec/spec_helper'
2
+ require 'rangetastic'
3
+ include Rangetastic
4
+
5
+ describe Order do
6
+
7
+ it "should have 25 orders" do
8
+ Order.count.should == 25
9
+ end
10
+
11
+ it "should respond to between" do
12
+ Order.respond_to?(:between).should == true
13
+ end
14
+
15
+ it "should have 5 orders fulfilled that were ordered no more than 10 days ago" do
16
+ Order.fulfilled.between(10.days.ago, 1.day.ago,"ordered_on").size.should == 5
17
+ end
18
+
19
+ it "should raise an error if the field is not in fields => []" do
20
+ lambda{ Order.fulfilled.between(1.week.ago, 1.day.ago, "not_a_field") }.should raise_error(ActiveRecord::StatementInvalid)
21
+ end
22
+
23
+ it "should be able to filter on any field that is in fields => []" do
24
+ %w(ordered_on fulfilled_on shipped_at).each do |field|
25
+ lambda{ Order.fulfilled.between(1.week.ago, 1.day.ago, field) }.should_not raise_error(ActiveRecord::StatementInvalid)
26
+ end
27
+ end
28
+
29
+ it "should have 5 orders fulfilled that were ordered no more than 10 days ago - 3" do
30
+ Order.fulfilled.ordered_between(10.days.ago, 1.day.ago).size.should == 5
31
+ end
32
+
33
+ %w(ordered shipped fulfilled created updated).each do |field|
34
+ it "should be able to access #{field}_between" do
35
+ lambda{ Order.send("#{field}_between", 1.day.ago, Date.today) }.should_not raise_error(NoMethodError)
36
+ end
37
+ end
38
+
39
+ it "should raise no method error when a field doesn't exist" do
40
+ lambda{ Order.eaten_between(1.day.ago, Date.today) }.should raise_error(NoMethodError)
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ # Inspiration gained from Thinking Sphinx's test suite via Ryan Bigg's by_star test suite.
2
+
3
+ $:.unshift File.dirname(__FILE__) + '/../lib'
4
+
5
+ require 'rubygems'
6
+ require 'activerecord'
7
+ require 'rangetastic'
8
+ require 'spec/fixtures/models'
9
+ require 'spec/test_helper'
10
+
11
+ FileUtils.mkdir_p "#{Dir.pwd}/tmp"
12
+
13
+ ActiveRecord::Base.logger = Logger.new(StringIO.new)
14
+
15
+ Spec::Runner.configure do |config|
16
+ test = TestHelper.new
17
+ test.setup_postgresql
18
+ end
@@ -0,0 +1,42 @@
1
+ class TestHelper
2
+ attr_accessor :host, :username, :password
3
+ attr_reader :path
4
+
5
+ def initialize
6
+ @host = "localhost"
7
+ @username = "chris" #Insert username for db here
8
+ @password = ""
9
+
10
+ @path = File.expand_path(File.dirname(__FILE__))
11
+ end
12
+
13
+ def setup_postgresql
14
+ ActiveRecord::Base.establish_connection(
15
+ :adapter => 'postgresql',
16
+ :database => 'rangetastic',
17
+ :username => @username,
18
+ :password => @password,
19
+ :host => @host
20
+ )
21
+ ActiveRecord::Base.logger = Logger.new(File.open("tmp/activerecord.log", "a"))
22
+
23
+ structure = File.open("spec/fixtures/structure.sql") { |f| f.read.chomp }
24
+ structure.split(';').each { |table|
25
+ ActiveRecord::Base.connection.execute table
26
+ }
27
+
28
+ 10.times do
29
+ Order.create(:ordered_on => 2.weeks.ago, :fulfilled_on => 2.days.ago)
30
+ end
31
+
32
+ 10.times do
33
+ Order.create(:ordered_on => 3.weeks.ago, :fulfilled_on => 2.days.ago)
34
+ end
35
+
36
+ 5.times do
37
+ Order.create(:ordered_on => 1.weeks.ago, :fulfilled_on => 2.days.ago)
38
+ end
39
+
40
+ end
41
+
42
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rangetastic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.2
5
+ platform: ruby
6
+ authors:
7
+ - Chris Herring
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-20 00:00:00 +10:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Chain a date range to any named_scope on any date field with specified white listed fields
17
+ email: chris.herring.iphone@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ - lib/rangetastic.rb
25
+ files:
26
+ - MIT-License
27
+ - Manifest
28
+ - README.markdown
29
+ - Rakefile
30
+ - lib/rangetastic.rb
31
+ - rangetastic.gemspec
32
+ - spec/fixtures/models.rb
33
+ - spec/fixtures/structure.sql
34
+ - spec/rangetastic_spec.rb
35
+ - spec/spec_helper.rb
36
+ - spec/test_helper.rb
37
+ has_rdoc: true
38
+ homepage: http://github.com/cherring/rangetastic
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --line-numbers
44
+ - --inline-source
45
+ - --title
46
+ - Rangetastic
47
+ - --main
48
+ - README.markdown
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "1.2"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project: rangetastic
66
+ rubygems_version: 1.3.4
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Chain a date range to any named_scope on any date field with specified white listed fields
70
+ test_files: []
71
+