fake_arel 0.1
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/History.txt +4 -0
- data/Manifest.txt +23 -0
- data/README.rdoc +70 -0
- data/Rakefile +24 -0
- data/fake_arel.gemspec +21 -0
- data/lib/fake_arel/extensions.rb +117 -0
- data/lib/fake_arel/rails_3_finders.rb +31 -0
- data/lib/fake_arel/singleton_class.rb +13 -0
- data/lib/fake_arel/with_scope_replacement.rb +87 -0
- data/lib/fake_arel.rb +14 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/fake_arel_spec.rb +45 -0
- data/spec/fixtures/replies.yml +29 -0
- data/spec/fixtures/reply.rb +18 -0
- data/spec/fixtures/schema.rb +17 -0
- data/spec/fixtures/topic.rb +10 -0
- data/spec/fixtures/topics.yml +30 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/test.db +0 -0
- data/tasks/rspec.rake +21 -0
- metadata +143 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
History.txt
|
|
2
|
+
Manifest.txt
|
|
3
|
+
README.rdoc
|
|
4
|
+
Rakefile
|
|
5
|
+
fake_arel.gemspec
|
|
6
|
+
lib/fake_arel.rb
|
|
7
|
+
lib/fake_arel/extensions.rb
|
|
8
|
+
lib/fake_arel/rails_3_finders.rb
|
|
9
|
+
lib/fake_arel/singleton_class.rb
|
|
10
|
+
lib/fake_arel/with_scope_replacement.rb
|
|
11
|
+
script/console
|
|
12
|
+
script/destroy
|
|
13
|
+
script/generate
|
|
14
|
+
spec/fake_arel_spec.rb
|
|
15
|
+
spec/fixtures/replies.yml
|
|
16
|
+
spec/fixtures/reply.rb
|
|
17
|
+
spec/fixtures/schema.rb
|
|
18
|
+
spec/fixtures/topic.rb
|
|
19
|
+
spec/fixtures/topics.yml
|
|
20
|
+
spec/spec.opts
|
|
21
|
+
spec/spec_helper.rb
|
|
22
|
+
spec/test.db
|
|
23
|
+
tasks/rspec.rake
|
data/README.rdoc
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
== Fake_arel: Rails 3 Query Interface for Rails 2
|
|
2
|
+
|
|
3
|
+
http://github.com/gammons/fake_arel
|
|
4
|
+
|
|
5
|
+
== DESCRIPTION:
|
|
6
|
+
|
|
7
|
+
* Tired of waiting for Rails 3 and its new super-sweet query interface? Try fake_arel!
|
|
8
|
+
|
|
9
|
+
* Fake_arel is a gem that will simulate the new Rails 3 query interface, using named_scopes and a couple small patches to ActiveRecord.
|
|
10
|
+
|
|
11
|
+
* This should serve as a nice bridge between Rails 2 and Rails 3 apps, and can be removed once upgrading your app to rails 3, and everything (hopefully) should still work.
|
|
12
|
+
|
|
13
|
+
== SYNOPSIS:
|
|
14
|
+
|
|
15
|
+
* All the finders described on Pratik's blog have been implemented. (http://m.onkey.org/2010/1/22/active-record-query-interface)
|
|
16
|
+
|
|
17
|
+
Reply.where(:id => 1)
|
|
18
|
+
Reply.select("content,id").where("id > 1").order("id desc").limit(1)
|
|
19
|
+
Topic.joins(:replies).limit(1)
|
|
20
|
+
|
|
21
|
+
* Additionally, named_scopes are very similar to Rails 3 relations, in that they are lazily loaded.
|
|
22
|
+
|
|
23
|
+
>> Reply.where(:name => "John").class
|
|
24
|
+
ActiveRecord::NamedScope::Scope
|
|
25
|
+
|
|
26
|
+
* Also implemented was <tt>to_sql</tt>. <tt>to_sql</tt> will work on any chained query.
|
|
27
|
+
>> Topic.joins(:replies).limit(1).to_sql
|
|
28
|
+
"SELECT \"topics\".* FROM \"topics\" INNER JOIN \"replies\" ON replies.topic_id = topics.id LIMIT 1"
|
|
29
|
+
|
|
30
|
+
* <tt>named_scope</tt> was modified to include other <tt>named_scope</tt>s, so you can chain them together.
|
|
31
|
+
|
|
32
|
+
class Reply < ActiveRecord::Base
|
|
33
|
+
named_scope :by_john, where(:name => "John")
|
|
34
|
+
named_scope :recent, lambda {|t| where("created_at > ? ", t.minutes.ago) }
|
|
35
|
+
named_scope :recent_by_john, recent(15).by_john
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
== REQUIREMENTS:
|
|
40
|
+
|
|
41
|
+
* >= ActiveRecord 2.3.5
|
|
42
|
+
|
|
43
|
+
== INSTALL:
|
|
44
|
+
|
|
45
|
+
* gem install fake_arel
|
|
46
|
+
|
|
47
|
+
== LICENSE:
|
|
48
|
+
|
|
49
|
+
(The MIT License)
|
|
50
|
+
|
|
51
|
+
Copyright (c) 2010 FIXME full name
|
|
52
|
+
|
|
53
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
54
|
+
a copy of this software and associated documentation files (the
|
|
55
|
+
'Software'), to deal in the Software without restriction, including
|
|
56
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
57
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
58
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
59
|
+
the following conditions:
|
|
60
|
+
|
|
61
|
+
The above copyright notice and this permission notice shall be
|
|
62
|
+
included in all copies or substantial portions of the Software.
|
|
63
|
+
|
|
64
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
65
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
66
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
67
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
68
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
69
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
70
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
gem 'hoe', '>= 2.1.0'
|
|
3
|
+
require 'hoe'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
require './lib/fake_arel'
|
|
6
|
+
|
|
7
|
+
Hoe.plugin :newgem
|
|
8
|
+
# Hoe.plugin :website
|
|
9
|
+
# Hoe.plugin :cucumberfeatures
|
|
10
|
+
|
|
11
|
+
# Generate all the Rake tasks
|
|
12
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
|
13
|
+
$hoe = Hoe.spec 'fake_arel' do
|
|
14
|
+
self.developer 'Grant Ammons', 'grant@pipelinedealsco.com'
|
|
15
|
+
self.rubyforge_name = self.name # TODO this is default value
|
|
16
|
+
self.extra_deps = [['activerecord','>= 2.3.5']]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
require 'newgem/tasks'
|
|
20
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
|
21
|
+
|
|
22
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
|
23
|
+
remove_task :default
|
|
24
|
+
task :default => :spec
|
data/fake_arel.gemspec
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
|
4
|
+
|
|
5
|
+
require 'bundler/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |s|
|
|
8
|
+
s.name = "fake_arel"
|
|
9
|
+
s.version = "0.1"
|
|
10
|
+
s.platform = Gem::Platform::RUBY
|
|
11
|
+
s.author = "Grant Ammons"
|
|
12
|
+
s.email = ["grant@pipelinedealsco.com"]
|
|
13
|
+
s.homepage = "http://github.com/gammons/fake_arel"
|
|
14
|
+
s.summary = "A library that simulates Rails 3 ActiveRecord Arel calls using extensions to named_scope."
|
|
15
|
+
|
|
16
|
+
s.add_dependency(['activerecord','>=2.3.5'])
|
|
17
|
+
s.rubyforge_project 'fake_arel'
|
|
18
|
+
|
|
19
|
+
s.files = Dir.glob("{bin,lib}/**/*") + %w(LICENSE README.md ROADMAP.md CHANGELOG.md)
|
|
20
|
+
s.require_path = 'lib'
|
|
21
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module NamedScope
|
|
3
|
+
module ClassMethods
|
|
4
|
+
def named_scope(name, options = {}, &block)
|
|
5
|
+
name = name.to_sym
|
|
6
|
+
|
|
7
|
+
scopes[name] = lambda do |parent_scope, *args|
|
|
8
|
+
Scope.new(parent_scope, case options
|
|
9
|
+
when Hash
|
|
10
|
+
options
|
|
11
|
+
when Scope
|
|
12
|
+
options.proxy_options
|
|
13
|
+
when Proc
|
|
14
|
+
if self.model_name != parent_scope.model_name
|
|
15
|
+
options.bind(parent_scope).call(*args)
|
|
16
|
+
else
|
|
17
|
+
options.call(*args)
|
|
18
|
+
end
|
|
19
|
+
end, &block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
singleton_class.send :define_method, name do |*args|
|
|
23
|
+
scopes[name].call(self, *args)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
class Scope
|
|
29
|
+
attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined
|
|
30
|
+
[].methods.each do |m|
|
|
31
|
+
unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s)
|
|
32
|
+
delegate m, :to => :proxy_found
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
delegate :scopes, :with_scope, :scoped_methods, :to => :proxy_scope
|
|
37
|
+
|
|
38
|
+
def initialize(proxy_scope, options = {}, &block)
|
|
39
|
+
options = options.proxy_options if options.class == ActiveRecord::NamedScope::Scope
|
|
40
|
+
[options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
|
|
41
|
+
extend Module.new(&block) if block_given?
|
|
42
|
+
unless Scope === proxy_scope
|
|
43
|
+
@current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods)
|
|
44
|
+
end
|
|
45
|
+
@proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def reload
|
|
49
|
+
load_found; self
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def first(*args)
|
|
53
|
+
if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
|
|
54
|
+
proxy_found.first(*args)
|
|
55
|
+
else
|
|
56
|
+
find(:first, *args)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def last(*args)
|
|
61
|
+
if args.first.kind_of?(Integer) || (@found && !args.first.kind_of?(Hash))
|
|
62
|
+
proxy_found.last(*args)
|
|
63
|
+
else
|
|
64
|
+
find(:last, *args)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def size
|
|
69
|
+
@found ? @found.length : count
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def empty?
|
|
73
|
+
@found ? @found.empty? : count.zero?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def respond_to?(method, include_private = false)
|
|
77
|
+
super || @proxy_scope.respond_to?(method, include_private)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def any?
|
|
81
|
+
if block_given?
|
|
82
|
+
proxy_found.any? { |*block_args| yield(*block_args) }
|
|
83
|
+
else
|
|
84
|
+
!empty?
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
protected
|
|
89
|
+
def proxy_found
|
|
90
|
+
@found || load_found
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
def method_missing(method, *args, &block)
|
|
95
|
+
if scopes.include?(method)
|
|
96
|
+
scopes[method].call(self, *args)
|
|
97
|
+
else
|
|
98
|
+
with_scope({:find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {}}, :reverse_merge) do
|
|
99
|
+
method = :new if method == :build
|
|
100
|
+
if current_scoped_methods_when_defined && !scoped_methods.include?(current_scoped_methods_when_defined)
|
|
101
|
+
with_scope current_scoped_methods_when_defined do
|
|
102
|
+
proxy_scope.send(method, *args, &block)
|
|
103
|
+
end
|
|
104
|
+
else
|
|
105
|
+
proxy_scope.send(method, *args, &block)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def load_found
|
|
112
|
+
@found = find(:all)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Rails3Finders
|
|
2
|
+
|
|
3
|
+
def self.included(base)
|
|
4
|
+
base.class_eval do
|
|
5
|
+
|
|
6
|
+
# the default named scopes
|
|
7
|
+
named_scope :offset, lambda {|offset| {:offset => offset}}
|
|
8
|
+
named_scope :limit, lambda {|limit| {:limit => limit}}
|
|
9
|
+
named_scope :includes, lambda { |*includes| { :include => includes }}
|
|
10
|
+
named_scope :select, lambda {|*select| {:select => select }}
|
|
11
|
+
named_scope :order, lambda {|order| {:order => order }}
|
|
12
|
+
named_scope :joins, lambda {|*join| {:joins => join }}
|
|
13
|
+
named_scope :from, lambda {|*from| {:from => from }}
|
|
14
|
+
named_scope :having, lambda {|*having| {:having => having }}
|
|
15
|
+
named_scope :group, lambda {|*group| {:group => group }}
|
|
16
|
+
named_scope :readonly, lambda {|readonly| {:readonly => readonly }}
|
|
17
|
+
named_scope :lock, lambda {|lock| {:lock => lock }}
|
|
18
|
+
|
|
19
|
+
__where_fn = lambda do |*where|
|
|
20
|
+
if where.is_a?(Array) and where.size == 1
|
|
21
|
+
{:conditions => where.first}
|
|
22
|
+
else
|
|
23
|
+
{:conditions => where}
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
named_scope :where, __where_fn
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class Object
|
|
2
|
+
# Returns the object's singleton class.
|
|
3
|
+
def singleton_class
|
|
4
|
+
class << self
|
|
5
|
+
self
|
|
6
|
+
end
|
|
7
|
+
end unless respond_to?(:singleton_class)
|
|
8
|
+
|
|
9
|
+
# class_eval on an object acts like singleton_class_eval.
|
|
10
|
+
def class_eval(*args, &block)
|
|
11
|
+
singleton_class.class_eval(*args, &block)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
class Base
|
|
3
|
+
|
|
4
|
+
def self.grant_scope_2
|
|
5
|
+
p "BANGO"
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
module WithScopeReplacement
|
|
11
|
+
def self.included(base)
|
|
12
|
+
base.class_eval do
|
|
13
|
+
class << self
|
|
14
|
+
def to_sql
|
|
15
|
+
construct_finder_sql self.current_scoped_methods[:find]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def with_scope(method_scoping = {}, action = :merge, &block)
|
|
19
|
+
method_scoping = {:find => method_scoping.proxy_options} if method_scoping.class == ActiveRecord::NamedScope::Scope
|
|
20
|
+
method_scoping = method_scoping.method_scoping if method_scoping.respond_to?(:method_scoping)
|
|
21
|
+
|
|
22
|
+
# Dup first and second level of hash (method and params).
|
|
23
|
+
method_scoping = method_scoping.inject({}) do |hash, (method, params)|
|
|
24
|
+
hash[method] = (params == true) ? params : params.dup
|
|
25
|
+
hash
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
method_scoping.assert_valid_keys([ :find, :create ])
|
|
29
|
+
|
|
30
|
+
if f = method_scoping[:find]
|
|
31
|
+
f.assert_valid_keys(VALID_FIND_OPTIONS)
|
|
32
|
+
set_readonly_option! f
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Merge scopings
|
|
36
|
+
if [:merge, :reverse_merge].include?(action) && current_scoped_methods
|
|
37
|
+
method_scoping = current_scoped_methods.inject(method_scoping) do |hash, (method, params)|
|
|
38
|
+
case hash[method]
|
|
39
|
+
when Hash
|
|
40
|
+
if method == :find
|
|
41
|
+
(hash[method].keys + params.keys).uniq.each do |key|
|
|
42
|
+
merge = hash[method][key] && params[key] # merge if both scopes have the same key
|
|
43
|
+
if key == :conditions && merge
|
|
44
|
+
if params[key].is_a?(Hash) && hash[method][key].is_a?(Hash)
|
|
45
|
+
hash[method][key] = merge_conditions(hash[method][key].deep_merge(params[key]))
|
|
46
|
+
else
|
|
47
|
+
hash[method][key] = merge_conditions(params[key], hash[method][key])
|
|
48
|
+
end
|
|
49
|
+
elsif key == :include && merge
|
|
50
|
+
hash[method][key] = merge_includes(hash[method][key], params[key]).uniq
|
|
51
|
+
elsif key == :joins && merge
|
|
52
|
+
hash[method][key] = merge_joins(params[key], hash[method][key])
|
|
53
|
+
else
|
|
54
|
+
hash[method][key] = hash[method][key] || params[key]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
if action == :reverse_merge
|
|
59
|
+
hash[method] = hash[method].merge(params)
|
|
60
|
+
else
|
|
61
|
+
hash[method] = params.merge(hash[method])
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
else
|
|
65
|
+
hash[method] = params
|
|
66
|
+
end
|
|
67
|
+
hash
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
self.scoped_methods << method_scoping
|
|
72
|
+
begin
|
|
73
|
+
yield
|
|
74
|
+
ensure
|
|
75
|
+
self.scoped_methods.pop
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Works like with_scope, but discards any nested properties.
|
|
80
|
+
def with_exclusive_scope(method_scoping = {}, &block)
|
|
81
|
+
with_scope(method_scoping, :overwrite, &block)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
data/lib/fake_arel.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
|
3
|
+
|
|
4
|
+
require 'active_record' unless defined?(ActiveRecord)
|
|
5
|
+
require 'fake_arel/singleton_class'
|
|
6
|
+
require 'fake_arel/extensions'
|
|
7
|
+
require 'fake_arel/with_scope_replacement'
|
|
8
|
+
require 'fake_arel/rails_3_finders'
|
|
9
|
+
|
|
10
|
+
module FakeArel
|
|
11
|
+
VERSION = '0.1'
|
|
12
|
+
ActiveRecord::Base.send :include, Rails3Finders
|
|
13
|
+
ActiveRecord::Base.send :include, WithScopeReplacement
|
|
14
|
+
end
|
data/script/console
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# File: script/console
|
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
|
4
|
+
|
|
5
|
+
libs = " -r irb/completion"
|
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/fake_arel.rb'}"
|
|
9
|
+
puts "Loading fake_arel gem"
|
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/destroy'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rubigen'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
require 'rubygems'
|
|
8
|
+
require 'rubigen'
|
|
9
|
+
end
|
|
10
|
+
require 'rubigen/scripts/generate'
|
|
11
|
+
|
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
|
+
require 'reply'
|
|
3
|
+
require 'topic'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
describe "Basics" do
|
|
7
|
+
it "should accomplish basic where" do
|
|
8
|
+
Reply.where(:id => 1).first.id.should == 1
|
|
9
|
+
Reply.where("id = 1").first.id.should == 1
|
|
10
|
+
Reply.where("id = ?", 1).first.id.should == 1
|
|
11
|
+
|
|
12
|
+
Reply.recent.size.should == 1
|
|
13
|
+
Reply.recent_limit_1.all.size.should == 1
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should be able to use where and other named scopes within named scopes" do
|
|
17
|
+
Reply.arel_id.size.should == 1
|
|
18
|
+
Reply.arel_id.first.id.should == 1
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should be able to use where and other named scopes within a lambda" do
|
|
22
|
+
Reply.arel_id_with_lambda(1).size.should == 1
|
|
23
|
+
Reply.arel_id_with_lambda(1).first.id.should == 1
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should be able to use where and other named scopes within a nested lambda" do
|
|
27
|
+
Reply.arel_id_with_nested_lambda(1).size.should == 1
|
|
28
|
+
Reply.arel_id_with_nested_lambda(1).first.id.should == 1
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should be all chainable" do
|
|
32
|
+
replies = Reply.select("content,id").where("id > 1").order("id desc").limit(1)
|
|
33
|
+
replies.all.size.should == 1
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should work with scope and with exclusive scope" do
|
|
37
|
+
Reply.find_all_but_first.map(&:id).should == [2,3,4,5]
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
describe "to sql" do
|
|
42
|
+
it "should be able to output sql" do
|
|
43
|
+
Topic.joins(:replies).limit(1).to_sql
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
witty_retort:
|
|
2
|
+
id: 1
|
|
3
|
+
topic_id: 1
|
|
4
|
+
content: Birdman is better!
|
|
5
|
+
created_at: <%= 6.hours.ago.to_s(:db) %>
|
|
6
|
+
|
|
7
|
+
another:
|
|
8
|
+
id: 2
|
|
9
|
+
topic_id: 2
|
|
10
|
+
content: Nuh uh!
|
|
11
|
+
created_at: <%= 1.hour.ago.to_s(:db) %>
|
|
12
|
+
|
|
13
|
+
spam:
|
|
14
|
+
id: 3
|
|
15
|
+
topic_id: 1
|
|
16
|
+
content: Nice site!
|
|
17
|
+
created_at: <%= 1.hour.ago.to_s(:db) %>
|
|
18
|
+
|
|
19
|
+
decisive:
|
|
20
|
+
id: 4
|
|
21
|
+
topic_id: 4
|
|
22
|
+
content: "I'm getting to the bottom of this"
|
|
23
|
+
created_at: <%= 30.minutes.ago.to_s(:db) %>
|
|
24
|
+
|
|
25
|
+
brave:
|
|
26
|
+
id: 5
|
|
27
|
+
topic_id: 4
|
|
28
|
+
content: "AR doesn't scare me a bit"
|
|
29
|
+
created_at: <%= 10.minutes.ago.to_s(:db) %>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class Reply < ActiveRecord::Base
|
|
2
|
+
belongs_to :topic, :include => [:replies]
|
|
3
|
+
|
|
4
|
+
named_scope :recent, where('replies.created_at > ?', 15.minutes.ago)
|
|
5
|
+
named_scope :recent_limit_1, where('replies.created_at > ?', 15.minutes.ago).limit(1)
|
|
6
|
+
|
|
7
|
+
named_scope :arel_id, :conditions => "id = 1"
|
|
8
|
+
named_scope :arel_id_with_lambda, lambda {|aid| arel_id}
|
|
9
|
+
named_scope :arel_id_with_nested_lambda, lambda {|aid| arel_id_with_lambda(aid)}
|
|
10
|
+
|
|
11
|
+
validates_presence_of :content
|
|
12
|
+
|
|
13
|
+
def self.find_all_but_first
|
|
14
|
+
with_scope(where('id > 1')) do
|
|
15
|
+
self.all
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
ActiveRecord::Schema.define do
|
|
2
|
+
create_table "topics", :force => true do |t|
|
|
3
|
+
t.column "project_id", :integer
|
|
4
|
+
t.column "title", :string
|
|
5
|
+
t.column "subtitle", :string
|
|
6
|
+
t.column "content", :text
|
|
7
|
+
t.column "created_at", :datetime
|
|
8
|
+
t.column "updated_at", :datetime
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
create_table "replies", :force => true do |t|
|
|
12
|
+
t.column "content", :text
|
|
13
|
+
t.column "created_at", :datetime
|
|
14
|
+
t.column "updated_at", :datetime
|
|
15
|
+
t.column "topic_id", :integer
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
class Topic < ActiveRecord::Base
|
|
2
|
+
has_many :replies, :dependent => :destroy, :order => 'replies.created_at DESC'
|
|
3
|
+
belongs_to :project
|
|
4
|
+
|
|
5
|
+
named_scope :mentions_activerecord, :conditions => ['topics.title LIKE ?', '%ActiveRecord%']
|
|
6
|
+
|
|
7
|
+
named_scope :with_replies_starting_with, lambda { |text|
|
|
8
|
+
{ :conditions => "replies.content LIKE '#{text}%' ", :include => :replies }
|
|
9
|
+
}
|
|
10
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
futurama:
|
|
2
|
+
id: 1
|
|
3
|
+
title: Isnt futurama awesome?
|
|
4
|
+
subtitle: It really is, isnt it.
|
|
5
|
+
content: I like futurama
|
|
6
|
+
created_at: <%= 1.day.ago.to_s(:db) %>
|
|
7
|
+
updated_at:
|
|
8
|
+
|
|
9
|
+
harvey_birdman:
|
|
10
|
+
id: 2
|
|
11
|
+
title: Harvey Birdman is the king of all men
|
|
12
|
+
subtitle: yup
|
|
13
|
+
content: He really is
|
|
14
|
+
created_at: <%= 2.hours.ago.to_s(:db) %>
|
|
15
|
+
updated_at:
|
|
16
|
+
|
|
17
|
+
rails:
|
|
18
|
+
id: 3
|
|
19
|
+
project_id: 1
|
|
20
|
+
title: Rails is nice
|
|
21
|
+
subtitle: It makes me happy
|
|
22
|
+
content: except when I have to hack internals to fix pagination. even then really.
|
|
23
|
+
created_at: <%= 20.minutes.ago.to_s(:db) %>
|
|
24
|
+
|
|
25
|
+
ar:
|
|
26
|
+
id: 4
|
|
27
|
+
project_id: 1
|
|
28
|
+
title: ActiveRecord sometimes freaks me out
|
|
29
|
+
content: "I mean, what's the deal with eager loading?"
|
|
30
|
+
created_at: <%= 15.minutes.ago.to_s(:db) %>
|
data/spec/spec.opts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
gem 'rspec'
|
|
3
|
+
gem 'activerecord'
|
|
4
|
+
|
|
5
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
|
6
|
+
$:.unshift(File.dirname(__FILE__) + '/fixtures')
|
|
7
|
+
$:.unshift(File.dirname(__FILE__) + '/models')
|
|
8
|
+
|
|
9
|
+
require 'active_record'
|
|
10
|
+
require 'active_record/fixtures'
|
|
11
|
+
require 'fake_arel'
|
|
12
|
+
gem 'sqlite3-ruby'
|
|
13
|
+
|
|
14
|
+
require 'ruby-debug'
|
|
15
|
+
Debugger.start
|
|
16
|
+
|
|
17
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'spec/test.db')
|
|
18
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb'
|
|
19
|
+
|
|
20
|
+
ActiveRecord::Base.silence do
|
|
21
|
+
ActiveRecord::Migration.verbose = false
|
|
22
|
+
|
|
23
|
+
# load schema
|
|
24
|
+
load File.join('spec/fixtures/schema.rb')
|
|
25
|
+
# load fixtures
|
|
26
|
+
Fixtures.create_fixtures("spec/fixtures", ActiveRecord::Base.connection.tables)
|
|
27
|
+
end
|
data/spec/test.db
ADDED
|
Binary file
|
data/tasks/rspec.rake
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'spec'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
|
5
|
+
require 'spec'
|
|
6
|
+
end
|
|
7
|
+
begin
|
|
8
|
+
require 'spec/rake/spectask'
|
|
9
|
+
rescue LoadError
|
|
10
|
+
puts <<-EOS
|
|
11
|
+
To use rspec for testing you must install rspec gem:
|
|
12
|
+
gem install rspec
|
|
13
|
+
EOS
|
|
14
|
+
exit(0)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc "Run the specs under spec/models"
|
|
18
|
+
Spec::Rake::SpecTask.new do |t|
|
|
19
|
+
t.spec_opts = ['--options', "spec/spec.opts"]
|
|
20
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
|
21
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: fake_arel
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 9
|
|
5
|
+
prerelease: false
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
version: "0.1"
|
|
10
|
+
platform: ruby
|
|
11
|
+
authors:
|
|
12
|
+
- Grant Ammons
|
|
13
|
+
autorequire:
|
|
14
|
+
bindir: bin
|
|
15
|
+
cert_chain: []
|
|
16
|
+
|
|
17
|
+
date: 2010-07-23 00:00:00 -04:00
|
|
18
|
+
default_executable:
|
|
19
|
+
dependencies:
|
|
20
|
+
- !ruby/object:Gem::Dependency
|
|
21
|
+
name: activerecord
|
|
22
|
+
prerelease: false
|
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
|
+
none: false
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
hash: 9
|
|
29
|
+
segments:
|
|
30
|
+
- 2
|
|
31
|
+
- 3
|
|
32
|
+
- 5
|
|
33
|
+
version: 2.3.5
|
|
34
|
+
type: :runtime
|
|
35
|
+
version_requirements: *id001
|
|
36
|
+
- !ruby/object:Gem::Dependency
|
|
37
|
+
name: rubyforge
|
|
38
|
+
prerelease: false
|
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
40
|
+
none: false
|
|
41
|
+
requirements:
|
|
42
|
+
- - ">="
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
hash: 7
|
|
45
|
+
segments:
|
|
46
|
+
- 2
|
|
47
|
+
- 0
|
|
48
|
+
- 4
|
|
49
|
+
version: 2.0.4
|
|
50
|
+
type: :development
|
|
51
|
+
version_requirements: *id002
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: hoe
|
|
54
|
+
prerelease: false
|
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
56
|
+
none: false
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
hash: 21
|
|
61
|
+
segments:
|
|
62
|
+
- 2
|
|
63
|
+
- 6
|
|
64
|
+
- 1
|
|
65
|
+
version: 2.6.1
|
|
66
|
+
type: :development
|
|
67
|
+
version_requirements: *id003
|
|
68
|
+
description: |-
|
|
69
|
+
* Tired of waiting for Rails 3 and its new super-sweet query interface? Try fake_arel!
|
|
70
|
+
|
|
71
|
+
* Fake_arel is a gem that will simulate the new Rails 3 query interface, using named_scopes and a couple small patches to ActiveRecord.
|
|
72
|
+
|
|
73
|
+
* This should serve as a nice bridge between Rails 2 and Rails 3 apps, and can be removed once upgrading your app to rails 3, and everything (hopefully) should still work.
|
|
74
|
+
email:
|
|
75
|
+
- grant@pipelinedealsco.com
|
|
76
|
+
executables: []
|
|
77
|
+
|
|
78
|
+
extensions: []
|
|
79
|
+
|
|
80
|
+
extra_rdoc_files:
|
|
81
|
+
- History.txt
|
|
82
|
+
- Manifest.txt
|
|
83
|
+
files:
|
|
84
|
+
- History.txt
|
|
85
|
+
- Manifest.txt
|
|
86
|
+
- README.rdoc
|
|
87
|
+
- Rakefile
|
|
88
|
+
- fake_arel.gemspec
|
|
89
|
+
- lib/fake_arel.rb
|
|
90
|
+
- lib/fake_arel/extensions.rb
|
|
91
|
+
- lib/fake_arel/rails_3_finders.rb
|
|
92
|
+
- lib/fake_arel/singleton_class.rb
|
|
93
|
+
- lib/fake_arel/with_scope_replacement.rb
|
|
94
|
+
- script/console
|
|
95
|
+
- script/destroy
|
|
96
|
+
- script/generate
|
|
97
|
+
- spec/fake_arel_spec.rb
|
|
98
|
+
- spec/fixtures/replies.yml
|
|
99
|
+
- spec/fixtures/reply.rb
|
|
100
|
+
- spec/fixtures/schema.rb
|
|
101
|
+
- spec/fixtures/topic.rb
|
|
102
|
+
- spec/fixtures/topics.yml
|
|
103
|
+
- spec/spec.opts
|
|
104
|
+
- spec/spec_helper.rb
|
|
105
|
+
- spec/test.db
|
|
106
|
+
- tasks/rspec.rake
|
|
107
|
+
has_rdoc: true
|
|
108
|
+
homepage: http://github.com/gammons/fake_arel
|
|
109
|
+
licenses: []
|
|
110
|
+
|
|
111
|
+
post_install_message:
|
|
112
|
+
rdoc_options:
|
|
113
|
+
- --main
|
|
114
|
+
- README.rdoc
|
|
115
|
+
require_paths:
|
|
116
|
+
- lib
|
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
|
+
none: false
|
|
119
|
+
requirements:
|
|
120
|
+
- - ">="
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
hash: 3
|
|
123
|
+
segments:
|
|
124
|
+
- 0
|
|
125
|
+
version: "0"
|
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
|
+
none: false
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
hash: 3
|
|
132
|
+
segments:
|
|
133
|
+
- 0
|
|
134
|
+
version: "0"
|
|
135
|
+
requirements: []
|
|
136
|
+
|
|
137
|
+
rubyforge_project: fake_arel
|
|
138
|
+
rubygems_version: 1.3.7
|
|
139
|
+
signing_key:
|
|
140
|
+
specification_version: 3
|
|
141
|
+
summary: "* Tired of waiting for Rails 3 and its new super-sweet query interface? Try fake_arel! * Fake_arel is a gem that will simulate the new Rails 3 query interface, using named_scopes and a couple small patches to ActiveRecord"
|
|
142
|
+
test_files: []
|
|
143
|
+
|