activerecord 3.0.0.beta2 → 3.0.0.beta3
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.
- data/CHANGELOG +11 -1
- data/lib/active_record/associations.rb +26 -54
- data/lib/active_record/associations/association_collection.rb +13 -2
- data/lib/active_record/associations/association_proxy.rb +3 -1
- data/lib/active_record/associations/through_association_scope.rb +1 -1
- data/lib/active_record/attribute_methods/dirty.rb +6 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -4
- data/lib/active_record/base.rb +66 -62
- data/lib/active_record/callbacks.rb +4 -2
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +5 -3
- data/lib/active_record/connection_adapters/abstract_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +45 -45
- data/lib/active_record/migration.rb +1 -1
- data/lib/active_record/named_scope.rb +26 -109
- data/lib/active_record/railties/databases.rake +3 -7
- data/lib/active_record/reflection.rb +11 -0
- data/lib/active_record/relation.rb +20 -1
- data/lib/active_record/relation/finder_methods.rb +18 -2
- data/lib/active_record/relation/predicate_builder.rb +4 -2
- data/lib/active_record/relation/query_methods.rb +26 -8
- data/lib/active_record/relation/spawn_methods.rb +9 -6
- data/lib/active_record/serializers/xml_serializer.rb +2 -1
- data/lib/active_record/validations/uniqueness.rb +3 -1
- data/lib/active_record/version.rb +1 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +5 -0
- data/lib/rails/generators/active_record/model/templates/module.rb +5 -0
- metadata +8 -7
@@ -84,15 +84,9 @@ namespace :db do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
when 'postgresql'
|
87
|
-
@encoding = config[
|
88
|
-
schema_search_path = config['schema_search_path'] || 'public'
|
89
|
-
first_in_schema_search_path = schema_search_path.split(',').first.strip
|
87
|
+
@encoding = config[:encoding] || ENV['CHARSET'] || 'utf8'
|
90
88
|
begin
|
91
89
|
ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
|
92
|
-
unless ActiveRecord::Base.connection.all_schemas.include?(first_in_schema_search_path)
|
93
|
-
ActiveRecord::Base.connection.create_schema(first_in_schema_search_path, config['username'])
|
94
|
-
$stderr.puts "Schema #{first_in_schema_search_path} has been created."
|
95
|
-
end
|
96
90
|
ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
|
97
91
|
ActiveRecord::Base.establish_connection(config)
|
98
92
|
rescue
|
@@ -452,6 +446,8 @@ namespace :db do
|
|
452
446
|
end
|
453
447
|
end
|
454
448
|
|
449
|
+
task 'test:prepare' => 'db:test:prepare'
|
450
|
+
|
455
451
|
def drop_database(config)
|
456
452
|
case config['adapter']
|
457
453
|
when 'mysql'
|
@@ -277,6 +277,17 @@ module ActiveRecord
|
|
277
277
|
!options[:validate].nil? ? options[:validate] : (options[:autosave] == true || macro == :has_many)
|
278
278
|
end
|
279
279
|
|
280
|
+
def dependent_conditions(record, base_class, extra_conditions)
|
281
|
+
dependent_conditions = []
|
282
|
+
dependent_conditions << "#{primary_key_name} = #{record.send(name).send(:owner_quoted_id)}"
|
283
|
+
dependent_conditions << "#{options[:as]}_type = '#{base_class.name}'" if options[:as]
|
284
|
+
dependent_conditions << klass.send(:sanitize_sql, options[:conditions]) if options[:conditions]
|
285
|
+
dependent_conditions << extra_conditions if extra_conditions
|
286
|
+
dependent_conditions = dependent_conditions.collect {|where| "(#{where})" }.join(" AND ")
|
287
|
+
dependent_conditions = dependent_conditions.gsub('@', '\@')
|
288
|
+
dependent_conditions
|
289
|
+
end
|
290
|
+
|
280
291
|
private
|
281
292
|
def derive_class_name
|
282
293
|
class_name = name.to_s.camelize
|
@@ -13,8 +13,9 @@ module ActiveRecord
|
|
13
13
|
delegate :insert, :to => :arel
|
14
14
|
|
15
15
|
attr_reader :table, :klass
|
16
|
+
attr_accessor :extensions
|
16
17
|
|
17
|
-
def initialize(klass, table)
|
18
|
+
def initialize(klass, table, &block)
|
18
19
|
@klass, @table = klass, table
|
19
20
|
|
20
21
|
@implicit_readonly = nil
|
@@ -22,6 +23,9 @@ module ActiveRecord
|
|
22
23
|
|
23
24
|
SINGLE_VALUE_METHODS.each {|v| instance_variable_set(:"@#{v}_value", nil)}
|
24
25
|
(ASSOCIATION_METHODS + MULTI_VALUE_METHODS).each {|v| instance_variable_set(:"@#{v}_values", [])}
|
26
|
+
@extensions = []
|
27
|
+
|
28
|
+
apply_modules(Module.new(&block)) if block_given?
|
25
29
|
end
|
26
30
|
|
27
31
|
def new(*args, &block)
|
@@ -307,11 +311,26 @@ module ActiveRecord
|
|
307
311
|
@should_eager_load ||= (@eager_load_values.any? || (@includes_values.any? && references_eager_loaded_tables?))
|
308
312
|
end
|
309
313
|
|
314
|
+
def ==(other)
|
315
|
+
case other
|
316
|
+
when Relation
|
317
|
+
other.to_sql == to_sql
|
318
|
+
when Array
|
319
|
+
to_a == other.to_a
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
def inspect
|
324
|
+
to_a.inspect
|
325
|
+
end
|
326
|
+
|
310
327
|
protected
|
311
328
|
|
312
329
|
def method_missing(method, *args, &block)
|
313
330
|
if Array.method_defined?(method)
|
314
331
|
to_a.send(method, *args, &block)
|
332
|
+
elsif @klass.scopes[method]
|
333
|
+
merge(@klass.send(method, *args, &block))
|
315
334
|
elsif @klass.respond_to?(method)
|
316
335
|
@klass.send(:with_scope, self) { @klass.send(method, *args, &block) }
|
317
336
|
elsif arel.respond_to?(method)
|
@@ -106,13 +106,29 @@ module ActiveRecord
|
|
106
106
|
# A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
|
107
107
|
# same arguments to this method as you can to <tt>find(:first)</tt>.
|
108
108
|
def first(*args)
|
109
|
-
args.any?
|
109
|
+
if args.any?
|
110
|
+
if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash))
|
111
|
+
to_a.first(*args)
|
112
|
+
else
|
113
|
+
apply_finder_options(args.first).first
|
114
|
+
end
|
115
|
+
else
|
116
|
+
find_first
|
117
|
+
end
|
110
118
|
end
|
111
119
|
|
112
120
|
# A convenience wrapper for <tt>find(:last, *args)</tt>. You can pass in all the
|
113
121
|
# same arguments to this method as you can to <tt>find(:last)</tt>.
|
114
122
|
def last(*args)
|
115
|
-
args.any?
|
123
|
+
if args.any?
|
124
|
+
if args.first.kind_of?(Integer) || (loaded? && !args.first.kind_of?(Hash))
|
125
|
+
to_a.last(*args)
|
126
|
+
else
|
127
|
+
apply_finder_options(args.first).last
|
128
|
+
end
|
129
|
+
else
|
130
|
+
find_last
|
131
|
+
end
|
116
132
|
end
|
117
133
|
|
118
134
|
# A convenience wrapper for <tt>find(:all, *args)</tt>. You can pass in all the
|
@@ -20,10 +20,12 @@ module ActiveRecord
|
|
20
20
|
table = Arel::Table.new(table_name, :engine => @engine)
|
21
21
|
end
|
22
22
|
|
23
|
-
attribute = table[column]
|
23
|
+
unless attribute = table[column]
|
24
|
+
raise StatementInvalid, "No attribute named `#{column}` exists for table `#{table.name}`"
|
25
|
+
end
|
24
26
|
|
25
27
|
case value
|
26
|
-
when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::
|
28
|
+
when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation
|
27
29
|
values = value.to_a
|
28
30
|
attribute.in(values)
|
29
31
|
when Range
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
1
2
|
require 'active_support/core_ext/object/blank'
|
2
3
|
|
3
4
|
module ActiveRecord
|
@@ -9,9 +10,10 @@ module ActiveRecord
|
|
9
10
|
attr_accessor :"#{query_method}_values"
|
10
11
|
|
11
12
|
next if [:where, :having].include?(query_method)
|
12
|
-
class_eval <<-CEVAL
|
13
|
-
def #{query_method}(*args)
|
13
|
+
class_eval <<-CEVAL, __FILE__
|
14
|
+
def #{query_method}(*args, &block)
|
14
15
|
new_relation = clone
|
16
|
+
new_relation.send(:apply_modules, Module.new(&block)) if block_given?
|
15
17
|
value = Array.wrap(args.flatten).reject {|x| x.blank? }
|
16
18
|
new_relation.#{query_method}_values += value if value.present?
|
17
19
|
new_relation
|
@@ -20,11 +22,12 @@ module ActiveRecord
|
|
20
22
|
end
|
21
23
|
|
22
24
|
[:where, :having].each do |query_method|
|
23
|
-
class_eval <<-CEVAL
|
24
|
-
def #{query_method}(*args)
|
25
|
+
class_eval <<-CEVAL, __FILE__
|
26
|
+
def #{query_method}(*args, &block)
|
25
27
|
new_relation = clone
|
28
|
+
new_relation.send(:apply_modules, Module.new(&block)) if block_given?
|
26
29
|
value = build_where(*args)
|
27
|
-
new_relation.#{query_method}_values +=
|
30
|
+
new_relation.#{query_method}_values += Array.wrap(value) if value.present?
|
28
31
|
new_relation
|
29
32
|
end
|
30
33
|
CEVAL
|
@@ -33,9 +36,10 @@ module ActiveRecord
|
|
33
36
|
ActiveRecord::Relation::SINGLE_VALUE_METHODS.each do |query_method|
|
34
37
|
attr_accessor :"#{query_method}_value"
|
35
38
|
|
36
|
-
class_eval <<-CEVAL
|
37
|
-
def #{query_method}(value = true)
|
39
|
+
class_eval <<-CEVAL, __FILE__
|
40
|
+
def #{query_method}(value = true, &block)
|
38
41
|
new_relation = clone
|
42
|
+
new_relation.send(:apply_modules, Module.new(&block)) if block_given?
|
39
43
|
new_relation.#{query_method}_value = value
|
40
44
|
new_relation
|
41
45
|
end
|
@@ -43,8 +47,16 @@ module ActiveRecord
|
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
46
|
-
def
|
50
|
+
def extending(*modules)
|
51
|
+
new_relation = clone
|
52
|
+
new_relation.send :apply_modules, *modules
|
53
|
+
new_relation
|
54
|
+
end
|
55
|
+
|
56
|
+
def lock(locks = true, &block)
|
47
57
|
relation = clone
|
58
|
+
relation.send(:apply_modules, Module.new(&block)) if block_given?
|
59
|
+
|
48
60
|
case locks
|
49
61
|
when String, TrueClass, NilClass
|
50
62
|
clone.tap {|new_relation| new_relation.lock_value = locks || true }
|
@@ -191,6 +203,12 @@ module ActiveRecord
|
|
191
203
|
|
192
204
|
private
|
193
205
|
|
206
|
+
def apply_modules(modules)
|
207
|
+
values = Array.wrap(modules)
|
208
|
+
@extensions += values if values.present?
|
209
|
+
values.each {|extension| extend(extension) }
|
210
|
+
end
|
211
|
+
|
194
212
|
def reverse_sql_order(order_query)
|
195
213
|
order_query.to_s.split(/,/).each { |s|
|
196
214
|
if s.match(/\s(asc|ASC)$/)
|
@@ -6,10 +6,9 @@ module ActiveRecord
|
|
6
6
|
merged_relation = clone
|
7
7
|
return merged_relation unless r
|
8
8
|
|
9
|
-
(
|
10
|
-
|
11
|
-
|
12
|
-
end
|
9
|
+
(Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).reject {|m| [:joins, :where].include?(m)}.each do |method|
|
10
|
+
value = r.send(:"#{method}_values")
|
11
|
+
merged_relation.send(:"#{method}_values=", value) if value.present?
|
13
12
|
end
|
14
13
|
|
15
14
|
merged_relation = merged_relation.joins(r.joins_values)
|
@@ -26,7 +25,7 @@ module ActiveRecord
|
|
26
25
|
|
27
26
|
merged_relation.where_values = merged_wheres
|
28
27
|
|
29
|
-
|
28
|
+
Relation::SINGLE_VALUE_METHODS.reject {|m| m == :lock}.each do |method|
|
30
29
|
unless (value = r.send(:"#{method}_value")).nil?
|
31
30
|
merged_relation.send(:"#{method}_value=", value)
|
32
31
|
end
|
@@ -34,6 +33,9 @@ module ActiveRecord
|
|
34
33
|
|
35
34
|
merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
|
36
35
|
|
36
|
+
# Apply scope extension modules
|
37
|
+
merged_relation.send :apply_modules, r.extensions
|
38
|
+
|
37
39
|
merged_relation
|
38
40
|
end
|
39
41
|
|
@@ -69,7 +71,7 @@ module ActiveRecord
|
|
69
71
|
result
|
70
72
|
end
|
71
73
|
|
72
|
-
VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset,
|
74
|
+
VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset, :extend,
|
73
75
|
:order, :select, :readonly, :group, :having, :from, :lock ]
|
74
76
|
|
75
77
|
def apply_finder_options(options)
|
@@ -84,6 +86,7 @@ module ActiveRecord
|
|
84
86
|
|
85
87
|
relation = relation.where(options[:conditions]) if options.has_key?(:conditions)
|
86
88
|
relation = relation.includes(options[:include]) if options.has_key?(:include)
|
89
|
+
relation = relation.extending(options[:extend]) if options.has_key?(:extend)
|
87
90
|
|
88
91
|
relation
|
89
92
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
1
2
|
require 'active_support/core_ext/hash/conversions'
|
2
3
|
|
3
4
|
module ActiveRecord #:nodoc:
|
@@ -186,7 +187,7 @@ module ActiveRecord #:nodoc:
|
|
186
187
|
end
|
187
188
|
|
188
189
|
def serializable_method_attributes
|
189
|
-
Array(options[:methods]).inject([]) do |method_attributes, name|
|
190
|
+
Array.wrap(options[:methods]).inject([]) do |method_attributes, name|
|
190
191
|
method_attributes << MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s)
|
191
192
|
method_attributes
|
192
193
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Validations
|
3
5
|
class UniquenessValidator < ActiveModel::EachValidator
|
@@ -19,7 +21,7 @@ module ActiveRecord
|
|
19
21
|
|
20
22
|
relation = table.where(sql, *params)
|
21
23
|
|
22
|
-
Array(options[:scope]).each do |scope_item|
|
24
|
+
Array.wrap(options[:scope]).each do |scope_item|
|
23
25
|
scope_value = record.send(scope_item)
|
24
26
|
relation = relation.where(scope_item => scope_value)
|
25
27
|
end
|
@@ -20,6 +20,11 @@ module ActiveRecord
|
|
20
20
|
template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
|
21
21
|
end
|
22
22
|
|
23
|
+
def create_module_file
|
24
|
+
return if class_path.empty?
|
25
|
+
template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb")
|
26
|
+
end
|
27
|
+
|
23
28
|
hook_for :test_framework
|
24
29
|
|
25
30
|
protected
|
metadata
CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 3
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 3.0.0.
|
9
|
+
- beta3
|
10
|
+
version: 3.0.0.beta3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- David Heinemeier Hansson
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-04-
|
18
|
+
date: 2010-04-13 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -29,8 +29,8 @@ dependencies:
|
|
29
29
|
- 3
|
30
30
|
- 0
|
31
31
|
- 0
|
32
|
-
-
|
33
|
-
version: 3.0.0.
|
32
|
+
- beta3
|
33
|
+
version: 3.0.0.beta3
|
34
34
|
type: :runtime
|
35
35
|
version_requirements: *id001
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -44,8 +44,8 @@ dependencies:
|
|
44
44
|
- 3
|
45
45
|
- 0
|
46
46
|
- 0
|
47
|
-
-
|
48
|
-
version: 3.0.0.
|
47
|
+
- beta3
|
48
|
+
version: 3.0.0.beta3
|
49
49
|
type: :runtime
|
50
50
|
version_requirements: *id002
|
51
51
|
- !ruby/object:Gem::Dependency
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- lib/rails/generators/active_record/model/model_generator.rb
|
155
155
|
- lib/rails/generators/active_record/model/templates/migration.rb
|
156
156
|
- lib/rails/generators/active_record/model/templates/model.rb
|
157
|
+
- lib/rails/generators/active_record/model/templates/module.rb
|
157
158
|
- lib/rails/generators/active_record/observer/observer_generator.rb
|
158
159
|
- lib/rails/generators/active_record/observer/templates/observer.rb
|
159
160
|
- lib/rails/generators/active_record/session_migration/session_migration_generator.rb
|