edge_rider 0.2.5 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +15 -0
  2. data/.ruby-version +1 -0
  3. data/.travis.yml +1 -0
  4. data/README.md +24 -8
  5. data/Rakefile +9 -2
  6. data/lib/edge_rider.rb +1 -2
  7. data/lib/edge_rider/preload_associations.rb +8 -2
  8. data/lib/edge_rider/scoped.rb +30 -0
  9. data/lib/edge_rider/traverse_association.rb +4 -2
  10. data/lib/edge_rider/util.rb +25 -0
  11. data/lib/edge_rider/version.rb +1 -1
  12. data/spec/rails-2.3/.ruby-version +1 -0
  13. data/spec/rails-2.3/Gemfile +4 -1
  14. data/spec/rails-2.3/Gemfile.lock +2 -2
  15. data/spec/rails-2.3/spec.opts +1 -0
  16. data/spec/rails-3.0/.ruby-version +1 -0
  17. data/spec/rails-3.0/Gemfile +1 -1
  18. data/spec/rails-3.0/Gemfile.lock +2 -2
  19. data/spec/rails-3.2/.ruby-version +1 -0
  20. data/spec/rails-3.2/Gemfile +1 -1
  21. data/spec/rails-3.2/Gemfile.lock +2 -2
  22. data/spec/rails-3.2/Rakefile +1 -0
  23. data/spec/rails-4.1/.rspec +2 -0
  24. data/spec/rails-4.1/.ruby-version +1 -0
  25. data/spec/rails-4.1/Gemfile +14 -0
  26. data/spec/rails-4.1/Gemfile.lock +138 -0
  27. data/spec/rails-4.1/Rakefile +12 -0
  28. data/spec/rails-4.1/app_root/.gitignore +16 -0
  29. data/spec/rails-4.1/app_root/bin/bundle +3 -0
  30. data/spec/rails-4.1/app_root/bin/rails +8 -0
  31. data/spec/rails-4.1/app_root/bin/rake +8 -0
  32. data/spec/rails-4.1/app_root/bin/spring +18 -0
  33. data/spec/rails-4.1/app_root/config/application.rb +28 -0
  34. data/spec/rails-4.1/app_root/config/boot.rb +4 -0
  35. data/spec/rails-4.1/app_root/config/environment.rb +5 -0
  36. data/spec/rails-4.1/app_root/config/environments/development.rb +37 -0
  37. data/spec/rails-4.1/app_root/config/environments/production.rb +83 -0
  38. data/spec/rails-4.1/app_root/config/environments/test.rb +39 -0
  39. data/spec/rails-4.1/app_root/config/initializers/backtrace_silencers.rb +7 -0
  40. data/spec/rails-4.1/app_root/config/initializers/cookies_serializer.rb +3 -0
  41. data/spec/rails-4.1/app_root/config/initializers/filter_parameter_logging.rb +4 -0
  42. data/spec/rails-4.1/app_root/config/initializers/inflections.rb +16 -0
  43. data/spec/rails-4.1/app_root/config/initializers/mime_types.rb +4 -0
  44. data/spec/rails-4.1/app_root/config/initializers/session_store.rb +3 -0
  45. data/spec/rails-4.1/app_root/config/initializers/wrap_parameters.rb +14 -0
  46. data/spec/rails-4.1/app_root/config/routes.rb +3 -0
  47. data/spec/rails-4.1/app_root/config/secrets.yml +22 -0
  48. data/spec/rails-4.1/rcov.opts +2 -0
  49. data/spec/rails-4.1/spec/spec_helper.rb +31 -0
  50. data/spec/shared/app_root/app/models/forum.rb +2 -1
  51. data/spec/shared/app_root/app/models/post.rb +2 -6
  52. data/spec/shared/app_root/app/models/topic.rb +3 -1
  53. data/spec/shared/app_root/app/models/user.rb +3 -2
  54. data/spec/shared/spec/edge_rider/scoped_spec.rb +54 -0
  55. data/spec/shared/spec/edge_rider/traverse_association_spec.rb +7 -6
  56. metadata +168 -58
  57. data/.rvmrc +0 -2
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODY2ODc4YmNlY2UxYjI4ZDBjMTRiZjg5ZGY1ZjM4Y2JhNzkyNDg2OA==
5
+ data.tar.gz: !binary |-
6
+ MGZhMTUwMWQxYWViNTQwMjVkMGQzZDE2YjljYTI1MmVlZThmNGFiYQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MjYyZDFkZWM4NDYzNmVlNjEwNTk1NjdhMWUyNzc3YmUxNTZjOTVjZTMxOTZh
10
+ MTQxMjBlMDdlMjQ4NmFmNWMxYWY4ZWFlMjA4MTQ2Y2UzNjQ2NmMyMDY1OTI3
11
+ ZTljOGE4NmQ3MzU3MzBhM2U2Y2UxZGQ3NmM3YzA2MThhZTM5NzE=
12
+ data.tar.gz: !binary |-
13
+ NzQ4NTM3NWIwN2EyYjcyZWM5ZjgwZjNiYzVjZDc0NjBmZjc4OTM5NDBiZTg3
14
+ NGI5NDU2MjM1MGU0MzI0MGE2YmQ1MGE1YzBkMDQwOGI4ODczMjE4NGEzNWJk
15
+ MTA5NDg2NzVlYTkyNTI3NTkyODI2ZjQ1ODQyOThiZTgxNjRiMTg=
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.3
data/.travis.yml CHANGED
@@ -2,6 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - "1.8.7"
4
4
  - "1.9.3"
5
+ - "2.1.0"
5
6
  - ree
6
7
  services:
7
8
  - mysql
data/README.md CHANGED
@@ -10,11 +10,11 @@ of scalable code with ActiveRecord, you are probably using relations (or scopes)
10
10
 
11
11
  Edge Rider was created with two intents:
12
12
 
13
- 1. Provides a number of utility methods to facilitate hardcore work with relations.
13
+ 1. Provide a number of utility methods to facilitate hardcore work with relations.
14
14
  2. Provide a stable API for working with relations across multiple versions of Rails (since
15
15
  Rails has a tradition of breaking details of its relation API every other release).
16
16
 
17
- It has been tested with Rails 2.3, 3.0 and 3.2.
17
+ It is tested with Rails 2.3, 3.0, 3.2 and 4.1, and on Ruby 1.8.7, 1.9.3 and 2.1.0.
18
18
 
19
19
 
20
20
  Usage
@@ -185,13 +185,8 @@ which Edge Rider merely makes public. Edge Rider ports this method forward to Ra
185
185
  ### Retrieve the class a relation is based on
186
186
 
187
187
  Edge Rider gives your relations a method `#origin_class` that returns the class the relation is based on.
188
- This is useful e.g. to perform unscoped method look-up.
188
+ This is useful e.g. to perform unscoped record look-up.
189
189
 
190
- # Rails 2 scope
191
- Post.recent.origin_class
192
- # => Post
193
-
194
- # Rails 3 relation
195
190
  Post.recent.origin_class
196
191
  # => Post
197
192
 
@@ -199,6 +194,27 @@ Note that `#origin_class` it roughly equivalent to the blockless form of [`unsco
199
194
  but it works consistently across all Rails versions.
200
195
 
201
196
 
197
+ ### Turn a model into a scope or narrow down an existing scope
198
+
199
+ Edge Rider ports `Model.scoped` forward to Rails 4+ (taken from
200
+ [activerecord-deprecated_finders](https://github.com/rails/activerecord-deprecated_finders/blob/master/lib/active_record/deprecated_finders/base.rb#L61)). This
201
+ enables you to consistently turn models into scopes or narrow down scopes
202
+ across all versions of Rails.
203
+
204
+ User.scoped # just calls User.all in Rails 4
205
+ User.active.scoped(conditions: { admin: true })
206
+
207
+ *Implementation note*: Rails 2 and 3 already have a method
208
+ [`.scoped`](http://apidock.com/rails/ActiveRecord/Scoping/Named/ClassMethods/scoped) which Edge Rider does not touch. Rails 4 has removed this method and
209
+ splits its functionality into the query methods known from Rails 3 (`.where`,
210
+ `.order` etc.) and an `.all` method that just returns a scope.
211
+
212
+ Note that associations and scopes also have a `.scoped` method that behaves
213
+ slightly different in all versions of Rails (see
214
+ [`scoped_spec.rb`](/spec/shared/spec/edge_rider/scoped_spec.rb#L49)). These
215
+ methods are not modified.
216
+
217
+
202
218
  Installation
203
219
  ------------
204
220
 
data/Rakefile CHANGED
@@ -54,7 +54,14 @@ end
54
54
  def for_each_directory_of(path, &block)
55
55
  Dir[path].sort.each do |rakefile|
56
56
  directory = File.dirname(rakefile)
57
- puts '', "\033[44m#{directory}\033[0m", ''
58
- block.call(directory)
57
+ puts '', "\033[4;34m# #{directory}\033[0m", '' # blue underline
58
+
59
+ if directory.include?('rails-2.3') and RUBY_VERSION != '1.8.7'
60
+ puts 'Skipping - Rails 2.3 requires Ruby 1.8.7'
61
+ elsif directory.include?('rails-4.1') and RUBY_VERSION == '1.8.7'
62
+ puts 'Skipping - Rails 4.1 does not support Ruby 1.8'
63
+ else
64
+ block.call(directory)
65
+ end
59
66
  end
60
67
  end
data/lib/edge_rider.rb CHANGED
@@ -7,8 +7,7 @@ require 'edge_rider/collect_column'
7
7
  require 'edge_rider/collect_ids'
8
8
  require 'edge_rider/preload_associations'
9
9
  require 'edge_rider/origin_class'
10
+ require 'edge_rider/scoped'
10
11
  require 'edge_rider/traverse_association'
11
12
  require 'edge_rider/to_id_query'
12
13
  require 'edge_rider/to_sql'
13
-
14
-
@@ -2,10 +2,16 @@ module EdgeRider
2
2
  module PreloadAssociations
3
3
 
4
4
  def preload_associations(*args)
5
- ActiveRecord::Associations::Preloader.new(*args).run
5
+ preloader = ActiveRecord::Associations::Preloader
6
+
7
+ if preloader.method_defined?(:preload) # Rails 4
8
+ preloader.new.preload(*args)
9
+ else
10
+ preloader.new(*args).run
11
+ end
6
12
  end
7
13
 
8
- if ActiveRecord::Base.respond_to?(:preload_associations, true) # Rails 2.3, Rails 3.0
14
+ if ActiveRecord::Base.respond_to?(:preload_associations, true) # Rails 2/3.0
9
15
  ActiveRecord::Base.class_eval do
10
16
  class << self
11
17
  public :preload_associations
@@ -0,0 +1,30 @@
1
+ module EdgeRider
2
+ module Scoped
3
+
4
+ VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset,
5
+ :order, :select, :readonly, :group, :having, :from, :lock ]
6
+
7
+ def scoped(options = nil)
8
+ options ||= {}
9
+ relation = all
10
+
11
+ options.assert_valid_keys(VALID_FIND_OPTIONS)
12
+ finders = options.dup
13
+ finders.delete_if { |key, value| value.nil? && key != :limit }
14
+
15
+ ((VALID_FIND_OPTIONS - [:conditions, :include]) & finders.keys).each do |finder|
16
+ relation = relation.send(finder, finders[finder])
17
+ end
18
+
19
+ relation = relation.where(finders[:conditions]) if options.has_key?(:conditions)
20
+ relation = relation.includes(finders[:include]) if options.has_key?(:include)
21
+
22
+ relation
23
+ end
24
+
25
+ if Rails.version.to_i >= 4
26
+ ActiveRecord::Base.extend(self)
27
+ end
28
+
29
+ end
30
+ end
@@ -13,8 +13,10 @@ module EdgeRider
13
13
  reflection = scope.reflect_on_association(association) or raise UnknownAssociation, "Could not find association: #{self.name}##{association}"
14
14
  foreign_key = reflection.respond_to?(:foreign_key) ? reflection.foreign_key : reflection.primary_key_name
15
15
 
16
- raise NotImplementedError if reflection.options[:conditions].present?
17
-
16
+ # In Rails 4, conditions on a scope are expressed as a lambda parameter
17
+ # that is called `scope`.
18
+ raise NotImplementedError if reflection.options[:conditions] or (reflection.respond_to?(:scope) && reflection.scope)
19
+
18
20
  if reflection.macro == :belongs_to # belongs_to
19
21
  ids = scope.collect_column(foreign_key, :distinct => true)
20
22
  scope = EdgeRider::Util.exclusive_query(reflection.klass, :id => ids)
@@ -27,6 +27,31 @@ module EdgeRider
27
27
  def scope?(object)
28
28
  object.respond_to?(:scoped)
29
29
  end
30
+
31
+ def define_scope(klass, name, lambda)
32
+ if Rails.version.to_i < 4 # Rails 2/3
33
+ scope_definition = Rails.version.to_i < 3 ? :named_scope : :scope
34
+ klass.send scope_definition, name, lambda
35
+ else
36
+ klass.send :scope, name, lambda { |*args|
37
+ options = lambda.call(*args)
38
+ klass.scoped(options.slice :conditions)
39
+ }
40
+ end
41
+ end
42
+
43
+ def define_association(owner, association, target, options)
44
+ if Rails.version.to_i < 4
45
+ owner.send association, target, options
46
+ else
47
+ # Reduce the options hash to the given keys and store the remainder in
48
+ # other_options. Using Hash#extract! would be easier to unterstand,
49
+ # but Rails 2 does not have it.
50
+ other_options = options.slice!(:conditions)
51
+ scope = lambda { |*args| scoped(options) }
52
+ owner.send association, target, scope, other_options
53
+ end
54
+ end
30
55
 
31
56
  def activerecord2?
32
57
  ActiveRecord::VERSION::MAJOR < 3
@@ -1,3 +1,3 @@
1
1
  module EdgeRider
2
- VERSION = '0.2.5'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1 @@
1
+ 1.8.7
@@ -1,4 +1,7 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
+
3
+ Deprecate.skip = true if defined?(Deprecate.skip)
4
+ Gem::Deprecate.skip = true if defined?(Gem::Deprecate.skip)
2
5
 
3
6
  gem 'rails', '~>2.3'
4
7
  gem 'rspec', '~>1.3'
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- edge_rider (0.2.4)
4
+ edge_rider (0.3.0)
5
5
  activerecord
6
6
 
7
7
  GEM
8
- remote: http://rubygems.org/
8
+ remote: https://rubygems.org/
9
9
  specs:
10
10
  actionmailer (2.3.18)
11
11
  actionpack (= 2.3.18)
@@ -2,3 +2,4 @@
2
2
  --format progress
3
3
  --loadby mtime
4
4
  --reverse
5
+ --backtrace
@@ -0,0 +1 @@
1
+ 1.9.3
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gem 'rails', '~>3.0.17'
4
4
  gem 'rspec'
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- edge_rider (0.2.4)
4
+ edge_rider (0.3.0)
5
5
  activerecord
6
6
 
7
7
  GEM
8
- remote: http://rubygems.org/
8
+ remote: https://rubygems.org/
9
9
  specs:
10
10
  abstract (1.0.0)
11
11
  actionmailer (3.0.20)
@@ -0,0 +1 @@
1
+ 1.9.3
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gem 'rails', '~>3.2.0'
4
4
  gem 'rspec'
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- edge_rider (0.2.4)
4
+ edge_rider (0.3.0)
5
5
  activerecord
6
6
 
7
7
  GEM
8
- remote: http://rubygems.org/
8
+ remote: https://rubygems.org/
9
9
  specs:
10
10
  actionmailer (3.2.14)
11
11
  actionpack (= 3.2.14)
@@ -8,4 +8,5 @@ desc "Run all specs for a specific rails version"
8
8
  RSpec::Core::RakeTask.new(:spec) do |t|
9
9
  t.pattern = defined?(SPEC) ? SPEC : ['**/*_spec.rb', '../shared/spec/**/*_spec.rb']
10
10
  t.verbose = false
11
+ t.rspec_opts = '-b'
11
12
  end
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format progress
@@ -0,0 +1 @@
1
+ 2.1.0
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~>4.1.0'
4
+ gem 'rspec'
5
+ gem 'rspec-rails'
6
+ gem 'mysql2'
7
+ gem 'rspec_candy'
8
+ gem 'debugger', platform: 'ruby_19'
9
+ gem 'database_cleaner', '=1.0.1'
10
+ gem 'andand'
11
+ gem 'has_defaults'
12
+ gem 'minitest' # fix MiniTest deprecation warnings
13
+
14
+ gem 'edge_rider', :path => '../..'
@@ -0,0 +1,138 @@
1
+ PATH
2
+ remote: ../..
3
+ specs:
4
+ edge_rider (0.3.0)
5
+ activerecord
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionmailer (4.1.0)
11
+ actionpack (= 4.1.0)
12
+ actionview (= 4.1.0)
13
+ mail (~> 2.5.4)
14
+ actionpack (4.1.0)
15
+ actionview (= 4.1.0)
16
+ activesupport (= 4.1.0)
17
+ rack (~> 1.5.2)
18
+ rack-test (~> 0.6.2)
19
+ actionview (4.1.0)
20
+ activesupport (= 4.1.0)
21
+ builder (~> 3.1)
22
+ erubis (~> 2.7.0)
23
+ activemodel (4.1.0)
24
+ activesupport (= 4.1.0)
25
+ builder (~> 3.1)
26
+ activerecord (4.1.0)
27
+ activemodel (= 4.1.0)
28
+ activesupport (= 4.1.0)
29
+ arel (~> 5.0.0)
30
+ activesupport (4.1.0)
31
+ i18n (~> 0.6, >= 0.6.9)
32
+ json (~> 1.7, >= 1.7.7)
33
+ minitest (~> 5.1)
34
+ thread_safe (~> 0.1)
35
+ tzinfo (~> 1.1)
36
+ andand (1.3.3)
37
+ arel (5.0.1.20140414130214)
38
+ builder (3.2.2)
39
+ columnize (0.3.6)
40
+ database_cleaner (1.0.1)
41
+ debugger (1.6.3)
42
+ columnize (>= 0.3.1)
43
+ debugger-linecache (~> 1.2.0)
44
+ debugger-ruby_core_source (~> 1.2.4)
45
+ debugger-linecache (1.2.0)
46
+ debugger-ruby_core_source (1.2.4)
47
+ diff-lcs (1.2.5)
48
+ erubis (2.7.0)
49
+ has_defaults (0.4.1)
50
+ activerecord
51
+ hike (1.2.3)
52
+ i18n (0.6.9)
53
+ json (1.8.1)
54
+ mail (2.5.4)
55
+ mime-types (~> 1.16)
56
+ treetop (~> 1.4.8)
57
+ mime-types (1.25.1)
58
+ minitest (5.3.4)
59
+ multi_json (1.10.1)
60
+ mysql2 (0.3.16)
61
+ polyglot (0.3.5)
62
+ rack (1.5.2)
63
+ rack-test (0.6.2)
64
+ rack (>= 1.0)
65
+ rails (4.1.0)
66
+ actionmailer (= 4.1.0)
67
+ actionpack (= 4.1.0)
68
+ actionview (= 4.1.0)
69
+ activemodel (= 4.1.0)
70
+ activerecord (= 4.1.0)
71
+ activesupport (= 4.1.0)
72
+ bundler (>= 1.3.0, < 2.0)
73
+ railties (= 4.1.0)
74
+ sprockets-rails (~> 2.0)
75
+ railties (4.1.0)
76
+ actionpack (= 4.1.0)
77
+ activesupport (= 4.1.0)
78
+ rake (>= 0.8.7)
79
+ thor (>= 0.18.1, < 2.0)
80
+ rake (10.3.2)
81
+ rspec (3.0.0)
82
+ rspec-core (~> 3.0.0)
83
+ rspec-expectations (~> 3.0.0)
84
+ rspec-mocks (~> 3.0.0)
85
+ rspec-core (3.0.0)
86
+ rspec-support (~> 3.0.0)
87
+ rspec-expectations (3.0.0)
88
+ diff-lcs (>= 1.2.0, < 2.0)
89
+ rspec-support (~> 3.0.0)
90
+ rspec-mocks (3.0.0)
91
+ rspec-support (~> 3.0.0)
92
+ rspec-rails (3.0.0)
93
+ actionpack (>= 3.0)
94
+ activesupport (>= 3.0)
95
+ railties (>= 3.0)
96
+ rspec-core (~> 3.0.0)
97
+ rspec-expectations (~> 3.0.0)
98
+ rspec-mocks (~> 3.0.0)
99
+ rspec-support (~> 3.0.0)
100
+ rspec-support (3.0.0)
101
+ rspec_candy (0.3.1)
102
+ rspec
103
+ sneaky-save
104
+ sneaky-save (0.0.5)
105
+ activerecord (>= 3.2.0)
106
+ sprockets (2.11.0)
107
+ hike (~> 1.2)
108
+ multi_json (~> 1.0)
109
+ rack (~> 1.0)
110
+ tilt (~> 1.1, != 1.3.0)
111
+ sprockets-rails (2.1.3)
112
+ actionpack (>= 3.0)
113
+ activesupport (>= 3.0)
114
+ sprockets (~> 2.8)
115
+ thor (0.19.1)
116
+ thread_safe (0.3.4)
117
+ tilt (1.4.1)
118
+ treetop (1.4.15)
119
+ polyglot
120
+ polyglot (>= 0.3.1)
121
+ tzinfo (1.2.1)
122
+ thread_safe (~> 0.1)
123
+
124
+ PLATFORMS
125
+ ruby
126
+
127
+ DEPENDENCIES
128
+ andand
129
+ database_cleaner (= 1.0.1)
130
+ debugger
131
+ edge_rider!
132
+ has_defaults
133
+ minitest
134
+ mysql2
135
+ rails (~> 4.1.0)
136
+ rspec
137
+ rspec-rails
138
+ rspec_candy