edge_rider 0.2.5 → 0.3.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.
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