activerecord 4.1.0.rc2 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -0
- data/lib/active_record/attribute_methods.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +74 -43
- data/lib/active_record/connection_handling.rb +6 -29
- data/lib/active_record/core.rb +1 -1
- data/lib/active_record/enum.rb +11 -6
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/reflection.rb +1 -1
- data/lib/active_record/relation/calculations.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +2 -2
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c715939fa3096f11569bb71814eb862c37e3d867
|
4
|
+
data.tar.gz: 715864fbf80ff9ea42f1f0ebaf440e70ed36d20d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c9b80fd916e8bda4351846bb9aea10068df857f59c56a22c38c41f713eb2226e52a2f100696bd0927b7d40e109e2c5d5d87e8504efc6e3ac96198168029276e
|
7
|
+
data.tar.gz: b52925316b715e276d48d60aece84bb0e8de1e0cfcd17191c9cabeb76730f43fe73a5203b3e83fb5bbc3a14899451205809f1301c6bc924c43d7501d17f15193
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
* Fixed a problem where an enum would overwrite values of another enum
|
2
|
+
with the same name in an unrelated class.
|
3
|
+
|
4
|
+
Fixes #14607.
|
5
|
+
|
6
|
+
*Evan Whalen*
|
7
|
+
|
8
|
+
* Block a few default Class methods as scope name.
|
9
|
+
|
10
|
+
For instance, this will raise:
|
11
|
+
|
12
|
+
scope :public, -> { where(status: 1) }
|
13
|
+
|
14
|
+
*arthurnn*
|
15
|
+
|
16
|
+
* Deprecate SQLite database URLs containing an
|
17
|
+
authority.
|
18
|
+
|
19
|
+
The current "correct" spellings for in-memory, relative, and
|
20
|
+
absolute URLs, respectively, are:
|
21
|
+
|
22
|
+
sqlite3::memory:
|
23
|
+
sqlite3:relative/path
|
24
|
+
sqlite3:/full/path
|
25
|
+
|
26
|
+
The previous spelling (`sqlite3:///relative/path`) continues to work
|
27
|
+
as it did in Rails 4.0, but with a deprecation warning: in the next
|
28
|
+
release, that spelling will instead be interpreted as an absolute
|
29
|
+
path.
|
30
|
+
|
31
|
+
*Matthew Draper*
|
32
|
+
|
1
33
|
* `where.not` adds `references` for `includes` like normal `where` calls do.
|
2
34
|
|
3
35
|
Fixes #14406.
|
@@ -29,6 +29,8 @@ module ActiveRecord
|
|
29
29
|
end
|
30
30
|
}
|
31
31
|
|
32
|
+
BLACKLISTED_CLASS_METHODS = %w(private public protected)
|
33
|
+
|
32
34
|
class AttributeMethodCache
|
33
35
|
def initialize
|
34
36
|
@module = Module.new
|
@@ -132,7 +134,7 @@ module ActiveRecord
|
|
132
134
|
# A class method is 'dangerous' if it is already (re)defined by Active Record, but
|
133
135
|
# not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
|
134
136
|
def dangerous_class_method?(method_name)
|
135
|
-
class_method_defined_within?(method_name, Base)
|
137
|
+
BLACKLISTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
|
136
138
|
end
|
137
139
|
|
138
140
|
def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc
|
@@ -33,9 +33,15 @@ module ActiveRecord
|
|
33
33
|
def initialize(url)
|
34
34
|
raise "Database URL cannot be empty" if url.blank?
|
35
35
|
@uri = URI.parse(url)
|
36
|
-
@adapter = @uri.scheme
|
36
|
+
@adapter = @uri.scheme.gsub('-', '_')
|
37
37
|
@adapter = "postgresql" if @adapter == "postgres"
|
38
|
-
|
38
|
+
|
39
|
+
if @uri.opaque
|
40
|
+
@uri.opaque, @query = @uri.opaque.split('?', 2)
|
41
|
+
else
|
42
|
+
@query = @uri.query
|
43
|
+
end
|
44
|
+
@authority = url =~ %r{\A[^:]*://}
|
39
45
|
end
|
40
46
|
|
41
47
|
# Converts the given URL to a full connection hash.
|
@@ -65,30 +71,51 @@ module ActiveRecord
|
|
65
71
|
# "localhost"
|
66
72
|
# # => {}
|
67
73
|
def query_hash
|
68
|
-
Hash[@query.split("&").map { |pair| pair.split("=") }]
|
74
|
+
Hash[(@query || '').split("&").map { |pair| pair.split("=") }]
|
69
75
|
end
|
70
76
|
|
71
77
|
def raw_config
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
78
|
+
if uri.opaque
|
79
|
+
query_hash.merge({
|
80
|
+
"adapter" => @adapter,
|
81
|
+
"database" => uri.opaque })
|
82
|
+
else
|
83
|
+
query_hash.merge({
|
84
|
+
"adapter" => @adapter,
|
85
|
+
"username" => uri.user,
|
86
|
+
"password" => uri.password,
|
87
|
+
"port" => uri.port,
|
88
|
+
"database" => database_from_path,
|
89
|
+
"host" => uri.host })
|
90
|
+
end
|
79
91
|
end
|
80
92
|
|
81
93
|
# Returns name of the database.
|
82
|
-
# Sqlite3
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
94
|
+
# Sqlite3's handling of a leading slash is in transition as of
|
95
|
+
# Rails 4.1.
|
96
|
+
def database_from_path
|
97
|
+
if @authority && @adapter == 'sqlite3'
|
98
|
+
# 'sqlite3:///foo' is relative, for backwards compatibility.
|
99
|
+
|
100
|
+
database_name = uri.path.sub(%r{^/}, "")
|
101
|
+
|
102
|
+
msg = "Paths in SQLite3 database URLs of the form `sqlite3:///path` will be treated as absolute in Rails 4.2. " \
|
103
|
+
"Please switch to `sqlite3:#{database_name}`."
|
104
|
+
ActiveSupport::Deprecation.warn(msg)
|
105
|
+
|
106
|
+
database_name
|
107
|
+
|
108
|
+
elsif @adapter == 'sqlite3'
|
109
|
+
# 'sqlite3:/foo' is absolute, because that makes sense. The
|
110
|
+
# corresponding relative version, 'sqlite3:foo', is handled
|
111
|
+
# elsewhere, as an "opaque".
|
112
|
+
|
113
|
+
uri.path
|
90
114
|
else
|
91
|
-
|
115
|
+
# Only SQLite uses a filename as the "database" name; for
|
116
|
+
# anything else, a leading slash would be silly.
|
117
|
+
|
118
|
+
uri.path.sub(%r{^/}, "")
|
92
119
|
end
|
93
120
|
end
|
94
121
|
end
|
@@ -124,7 +151,7 @@ module ActiveRecord
|
|
124
151
|
if config
|
125
152
|
resolve_connection config
|
126
153
|
elsif env = ActiveRecord::ConnectionHandling::RAILS_ENV.call
|
127
|
-
|
154
|
+
resolve_symbol_connection env.to_sym
|
128
155
|
else
|
129
156
|
raise AdapterNotSpecified
|
130
157
|
end
|
@@ -193,42 +220,41 @@ module ActiveRecord
|
|
193
220
|
#
|
194
221
|
def resolve_connection(spec)
|
195
222
|
case spec
|
196
|
-
when Symbol
|
197
|
-
|
223
|
+
when Symbol
|
224
|
+
resolve_symbol_connection spec
|
225
|
+
when String
|
226
|
+
resolve_string_connection spec
|
198
227
|
when Hash
|
199
228
|
resolve_hash_connection spec
|
200
229
|
end
|
201
230
|
end
|
202
231
|
|
232
|
+
def resolve_string_connection(spec)
|
233
|
+
# Rails has historically accepted a string to mean either
|
234
|
+
# an environment key or a URL spec, so we have deprecated
|
235
|
+
# this ambiguous behaviour and in the future this function
|
236
|
+
# can be removed in favor of resolve_url_connection.
|
237
|
+
if configurations.key?(spec) || spec !~ /:/
|
238
|
+
ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \
|
239
|
+
"for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead"
|
240
|
+
resolve_symbol_connection(spec)
|
241
|
+
else
|
242
|
+
resolve_url_connection(spec)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
203
246
|
# Takes the environment such as `:production` or `:development`.
|
204
247
|
# This requires that the @configurations was initialized with a key that
|
205
248
|
# matches.
|
206
249
|
#
|
207
|
-
#
|
208
|
-
# Resolver.new("production" => {}).resolve_env_connection(:production)
|
250
|
+
# Resolver.new("production" => {}).resolve_symbol_connection(:production)
|
209
251
|
# # => {}
|
210
252
|
#
|
211
|
-
|
212
|
-
#
|
213
|
-
# Resolver.new({}).resolve_env_connection("postgresql://localhost/foo")
|
214
|
-
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
|
215
|
-
#
|
216
|
-
def resolve_env_connection(spec)
|
217
|
-
# Rails has historically accepted a string to mean either
|
218
|
-
# an environment key or a URL spec, so we have deprecated
|
219
|
-
# this ambiguous behaviour and in the future this function
|
220
|
-
# can be removed in favor of resolve_string_connection and
|
221
|
-
# resolve_symbol_connection.
|
253
|
+
def resolve_symbol_connection(spec)
|
222
254
|
if config = configurations[spec.to_s]
|
223
|
-
if spec.is_a?(String)
|
224
|
-
ActiveSupport::Deprecation.warn "Passing a string to ActiveRecord::Base.establish_connection " \
|
225
|
-
"for a configuration lookup is deprecated, please pass a symbol (#{spec.to_sym.inspect}) instead"
|
226
|
-
end
|
227
255
|
resolve_connection(config)
|
228
|
-
elsif spec.is_a?(String)
|
229
|
-
resolve_string_connection(spec)
|
230
256
|
else
|
231
|
-
raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available
|
257
|
+
raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}")
|
232
258
|
end
|
233
259
|
end
|
234
260
|
|
@@ -244,7 +270,12 @@ module ActiveRecord
|
|
244
270
|
spec
|
245
271
|
end
|
246
272
|
|
247
|
-
|
273
|
+
# Takes a connection URL.
|
274
|
+
#
|
275
|
+
# Resolver.new({}).resolve_url_connection("postgresql://localhost/foo")
|
276
|
+
# # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
|
277
|
+
#
|
278
|
+
def resolve_url_connection(url)
|
248
279
|
ConnectionUrlResolver.new(url).to_hash
|
249
280
|
end
|
250
281
|
end
|
@@ -58,9 +58,9 @@ module ActiveRecord
|
|
58
58
|
end
|
59
59
|
|
60
60
|
class MergeAndResolveDefaultUrlConfig # :nodoc:
|
61
|
-
def initialize(raw_configurations
|
61
|
+
def initialize(raw_configurations)
|
62
62
|
@raw_config = raw_configurations.dup
|
63
|
-
@
|
63
|
+
@env = DEFAULT_ENV.call.to_s
|
64
64
|
end
|
65
65
|
|
66
66
|
# Returns fully resolved connection hashes.
|
@@ -71,33 +71,10 @@ module ActiveRecord
|
|
71
71
|
|
72
72
|
private
|
73
73
|
def config
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def raw_merged_into_default
|
82
|
-
default = default_url_hash
|
83
|
-
|
84
|
-
@raw_config.each do |env, values|
|
85
|
-
default[env] = values || {}
|
86
|
-
default[env].merge!("url" => @url) { |h, v1, v2| v1 || v2 } if default[env].is_a?(Hash)
|
87
|
-
end
|
88
|
-
default
|
89
|
-
end
|
90
|
-
|
91
|
-
# When the raw configuration is not present and ENV['DATABASE_URL']
|
92
|
-
# is available we return a hash with the connection information in
|
93
|
-
# the connection URL. This hash responds to any string key with
|
94
|
-
# resolved connection information.
|
95
|
-
def default_url_hash
|
96
|
-
Hash.new do |hash, key|
|
97
|
-
hash[key] = if key.is_a? String
|
98
|
-
ActiveRecord::ConnectionAdapters::ConnectionSpecification::ConnectionUrlResolver.new(@url).to_hash
|
99
|
-
else
|
100
|
-
nil
|
74
|
+
@raw_config.dup.tap do |cfg|
|
75
|
+
if url = ENV['DATABASE_URL']
|
76
|
+
cfg[@env] ||= {}
|
77
|
+
cfg[@env]["url"] ||= url
|
101
78
|
end
|
102
79
|
end
|
103
80
|
end
|
data/lib/active_record/core.rb
CHANGED
data/lib/active_record/enum.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/object/deep_dup'
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# Declare an enum attribute where the values map to integers in the database,
|
3
5
|
# but can be queried by name. Example:
|
@@ -65,10 +67,14 @@ module ActiveRecord
|
|
65
67
|
#
|
66
68
|
# Where conditions on an enum attribute must use the ordinal value of an enum.
|
67
69
|
module Enum
|
68
|
-
|
70
|
+
def self.extended(base)
|
71
|
+
base.class_attribute(:defined_enums)
|
72
|
+
base.defined_enums = {}
|
73
|
+
end
|
69
74
|
|
70
|
-
def
|
71
|
-
|
75
|
+
def inherited(base)
|
76
|
+
base.defined_enums = defined_enums.deep_dup
|
77
|
+
super
|
72
78
|
end
|
73
79
|
|
74
80
|
def enum(definitions)
|
@@ -122,9 +128,8 @@ module ActiveRecord
|
|
122
128
|
klass.send(:detect_enum_conflict!, name, value, true)
|
123
129
|
klass.scope value, -> { klass.where name => i }
|
124
130
|
end
|
125
|
-
|
126
|
-
DEFINED_ENUMS[name.to_s] = enum_values
|
127
131
|
end
|
132
|
+
defined_enums[name.to_s] = enum_values
|
128
133
|
end
|
129
134
|
end
|
130
135
|
|
@@ -134,7 +139,7 @@ module ActiveRecord
|
|
134
139
|
mod = Module.new do
|
135
140
|
private
|
136
141
|
def save_changed_attribute(attr_name, value)
|
137
|
-
if (mapping = self.class.
|
142
|
+
if (mapping = self.class.defined_enums[attr_name.to_s])
|
138
143
|
if attribute_changed?(attr_name)
|
139
144
|
old = changed_attributes[attr_name]
|
140
145
|
|
@@ -151,7 +151,7 @@ module ActiveRecord
|
|
151
151
|
super ||
|
152
152
|
other_aggregation.kind_of?(self.class) &&
|
153
153
|
name == other_aggregation.name &&
|
154
|
-
other_aggregation.options &&
|
154
|
+
!other_aggregation.options.nil? &&
|
155
155
|
active_record == other_aggregation.active_record
|
156
156
|
end
|
157
157
|
|
@@ -231,7 +231,7 @@ module ActiveRecord
|
|
231
231
|
|
232
232
|
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
|
233
233
|
# Postgresql doesn't like ORDER BY when there are no GROUP BY
|
234
|
-
relation =
|
234
|
+
relation = unscope(:order)
|
235
235
|
|
236
236
|
column_alias = column_name
|
237
237
|
|
@@ -93,8 +93,8 @@ module ActiveRecord
|
|
93
93
|
value
|
94
94
|
end
|
95
95
|
|
96
|
-
def map_enum_attribute(klass,attribute,value)
|
97
|
-
mapping = klass.
|
96
|
+
def map_enum_attribute(klass, attribute, value)
|
97
|
+
mapping = klass.defined_enums[attribute.to_s]
|
98
98
|
value = mapping[value] if value && mapping
|
99
99
|
value
|
100
100
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.0
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.1.0
|
19
|
+
version: 4.1.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.1.0
|
26
|
+
version: 4.1.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activemodel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 4.1.0
|
33
|
+
version: 4.1.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 4.1.0
|
40
|
+
version: 4.1.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: arel
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -242,9 +242,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
242
242
|
version: 1.9.3
|
243
243
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
244
244
|
requirements:
|
245
|
-
- - "
|
245
|
+
- - ">="
|
246
246
|
- !ruby/object:Gem::Version
|
247
|
-
version:
|
247
|
+
version: '0'
|
248
248
|
requirements: []
|
249
249
|
rubyforge_project:
|
250
250
|
rubygems_version: 2.2.0
|