activerecord 2.2.2 → 2.2.3
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 +4 -0
- data/Rakefile +7 -3
- data/lib/active_record/associations.rb +1 -1
- data/lib/active_record/associations/association_proxy.rb +2 -2
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +9 -3
- data/lib/active_record/base.rb +5 -3
- data/lib/active_record/connection_adapters/mysql_adapter.rb +5 -2
- data/lib/active_record/dirty.rb +3 -3
- data/lib/active_record/named_scope.rb +11 -2
- data/lib/active_record/reflection.rb +8 -0
- data/lib/active_record/transactions.rb +2 -2
- data/lib/active_record/version.rb +1 -1
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +11 -0
- data/test/cases/associations/inner_join_association_test.rb +5 -0
- data/test/cases/connection_test_mysql.rb +26 -0
- data/test/cases/dirty_test.rb +13 -1
- data/test/cases/helper.rb +2 -2
- data/test/cases/method_scoping_test.rb +4 -2
- data/test/cases/named_scope_test.rb +9 -0
- data/test/cases/validations_i18n_test.rb +4 -4
- data/test/connections/jdbc_jdbcderby/connection.rb +18 -0
- data/test/connections/jdbc_jdbch2/connection.rb +18 -0
- data/test/connections/jdbc_jdbchsqldb/connection.rb +18 -0
- data/test/connections/jdbc_jdbcmysql/connection.rb +26 -0
- data/test/connections/jdbc_jdbcpostgresql/connection.rb +26 -0
- data/test/connections/jdbc_jdbcsqlite3/connection.rb +25 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database.sqlite3 +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite3 +0 -0
- data/test/models/author.rb +2 -0
- data/test/models/post.rb +6 -0
- metadata +15 -47
data/CHANGELOG
CHANGED
data/Rakefile
CHANGED
@@ -32,9 +32,13 @@ task :default => :test
|
|
32
32
|
desc 'Run mysql, sqlite, and postgresql tests'
|
33
33
|
task :test => %w(test_mysql test_sqlite3 test_postgresql)
|
34
34
|
|
35
|
-
for adapter in %w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase openbase frontbase )
|
35
|
+
for adapter in %w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb )
|
36
36
|
Rake::TestTask.new("test_#{adapter}") { |t|
|
37
|
-
|
37
|
+
if adapter =~ /jdbc/
|
38
|
+
t.libs << "test" << "test/connections/jdbc_#{adapter}"
|
39
|
+
else
|
40
|
+
t.libs << "test" << "test/connections/native_#{adapter}"
|
41
|
+
end
|
38
42
|
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/]
|
39
43
|
t.test_files=Dir.glob( "test/cases/**/*_test{,_#{adapter_short}}.rb" ).sort
|
40
44
|
t.verbose = true
|
@@ -171,7 +175,7 @@ spec = Gem::Specification.new do |s|
|
|
171
175
|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
172
176
|
end
|
173
177
|
|
174
|
-
s.add_dependency('activesupport', '= 2.2.
|
178
|
+
s.add_dependency('activesupport', '= 2.2.3' + PKG_BUILD)
|
175
179
|
|
176
180
|
s.files.delete FIXTURES_ROOT + "/fixture_database.sqlite"
|
177
181
|
s.files.delete FIXTURES_ROOT + "/fixture_database_2.sqlite"
|
@@ -2159,7 +2159,7 @@ module ActiveRecord
|
|
2159
2159
|
klass.send(:type_condition, aliased_table_name)] unless klass.descends_from_active_record?
|
2160
2160
|
|
2161
2161
|
[through_reflection, reflection].each do |ref|
|
2162
|
-
join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions]))} " if ref && ref.options[:conditions]
|
2162
|
+
join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions], aliased_table_name))} " if ref && ref.options[:conditions]
|
2163
2163
|
end
|
2164
2164
|
|
2165
2165
|
join
|
@@ -169,8 +169,8 @@ module ActiveRecord
|
|
169
169
|
end
|
170
170
|
|
171
171
|
# Forwards the call to the reflection class.
|
172
|
-
def sanitize_sql(sql)
|
173
|
-
@reflection.klass.send(:sanitize_sql, sql)
|
172
|
+
def sanitize_sql(sql, table_name = @reflection.klass.quoted_table_name)
|
173
|
+
@reflection.klass.send(:sanitize_sql, sql, table_name)
|
174
174
|
end
|
175
175
|
|
176
176
|
# Assigns the ID of the owner to the corresponding foreign key in +record+.
|
@@ -9,6 +9,14 @@ module ActiveRecord
|
|
9
9
|
create_record(attributes) { |record| insert_record(record, true) }
|
10
10
|
end
|
11
11
|
|
12
|
+
def columns
|
13
|
+
@reflection.columns(@reflection.options[:join_table], "#{@reflection.options[:join_table]} Columns")
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset_column_information
|
17
|
+
@reflection.reset_column_information
|
18
|
+
end
|
19
|
+
|
12
20
|
protected
|
13
21
|
def construct_find_options!(options)
|
14
22
|
options[:joins] = @join_sql
|
@@ -32,8 +40,6 @@ module ActiveRecord
|
|
32
40
|
if @reflection.options[:insert_sql]
|
33
41
|
@owner.connection.insert(interpolate_sql(@reflection.options[:insert_sql], record))
|
34
42
|
else
|
35
|
-
columns = @owner.connection.columns(@reflection.options[:join_table], "#{@reflection.options[:join_table]} Columns")
|
36
|
-
|
37
43
|
attributes = columns.inject({}) do |attrs, column|
|
38
44
|
case column.name.to_s
|
39
45
|
when @reflection.primary_key_name.to_s
|
@@ -103,7 +109,7 @@ module ActiveRecord
|
|
103
109
|
# clause has been explicitly defined. Otherwise you can get broken records back, if, for example, the join column also has
|
104
110
|
# an id column. This will then overwrite the id column of the records coming back.
|
105
111
|
def finding_with_ambiguous_select?(select_clause)
|
106
|
-
!select_clause &&
|
112
|
+
!select_clause && columns.size != 2
|
107
113
|
end
|
108
114
|
|
109
115
|
private
|
data/lib/active_record/base.rb
CHANGED
@@ -1678,7 +1678,9 @@ module ActiveRecord #:nodoc:
|
|
1678
1678
|
scoped_order = scope[:order] if scope
|
1679
1679
|
if order
|
1680
1680
|
sql << " ORDER BY #{order}"
|
1681
|
-
|
1681
|
+
if scoped_order && scoped_order != order
|
1682
|
+
sql << ", #{scoped_order}"
|
1683
|
+
end
|
1682
1684
|
else
|
1683
1685
|
sql << " ORDER BY #{scoped_order}" if scoped_order
|
1684
1686
|
end
|
@@ -2072,12 +2074,12 @@ module ActiveRecord #:nodoc:
|
|
2072
2074
|
# ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
|
2073
2075
|
# { :name => "foo'bar", :group_id => 4 } returns "name='foo''bar' and group_id='4'"
|
2074
2076
|
# "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
|
2075
|
-
def sanitize_sql_for_conditions(condition)
|
2077
|
+
def sanitize_sql_for_conditions(condition, table_name = quoted_table_name)
|
2076
2078
|
return nil if condition.blank?
|
2077
2079
|
|
2078
2080
|
case condition
|
2079
2081
|
when Array; sanitize_sql_array(condition)
|
2080
|
-
when Hash; sanitize_sql_hash_for_conditions(condition)
|
2082
|
+
when Hash; sanitize_sql_hash_for_conditions(condition, table_name)
|
2081
2083
|
else condition
|
2082
2084
|
end
|
2083
2085
|
end
|
@@ -150,6 +150,7 @@ module ActiveRecord
|
|
150
150
|
# * <tt>:password</tt> - Defaults to nothing.
|
151
151
|
# * <tt>:database</tt> - The name of the database. No default, must be provided.
|
152
152
|
# * <tt>:encoding</tt> - (Optional) Sets the client encoding by executing "SET NAMES <encoding>" after connection.
|
153
|
+
# * <tt>:reconnect</tt> - Defaults to false (See MySQL documentation: http://dev.mysql.com/doc/refman/5.0/en/auto-reconnect.html).
|
153
154
|
# * <tt>:sslca</tt> - Necessary to use MySQL with an SSL connection.
|
154
155
|
# * <tt>:sslkey</tt> - Necessary to use MySQL with an SSL connection.
|
155
156
|
# * <tt>:sslcert</tt> - Necessary to use MySQL with an SSL connection.
|
@@ -534,8 +535,6 @@ module ActiveRecord
|
|
534
535
|
|
535
536
|
private
|
536
537
|
def connect
|
537
|
-
@connection.reconnect = true if @connection.respond_to?(:reconnect=)
|
538
|
-
|
539
538
|
encoding = @config[:encoding]
|
540
539
|
if encoding
|
541
540
|
@connection.options(Mysql::SET_CHARSET_NAME, encoding) rescue nil
|
@@ -546,6 +545,10 @@ module ActiveRecord
|
|
546
545
|
end
|
547
546
|
|
548
547
|
@connection.real_connect(*@connection_options)
|
548
|
+
|
549
|
+
# reconnect must be set after real_connect is called, because real_connect sets it to false internally
|
550
|
+
@connection.reconnect = !!@config[:reconnect] if @connection.respond_to?(:reconnect=)
|
551
|
+
|
549
552
|
configure_connection
|
550
553
|
end
|
551
554
|
|
data/lib/active_record/dirty.rb
CHANGED
@@ -151,12 +151,12 @@ module ActiveRecord
|
|
151
151
|
|
152
152
|
def field_changed?(attr, old, value)
|
153
153
|
if column = column_for_attribute(attr)
|
154
|
-
if column.
|
155
|
-
# For nullable
|
154
|
+
if column.number? && column.null && (old.nil? || old == 0) && value.blank?
|
155
|
+
# For nullable numeric columns, NULL gets stored in database for blank (i.e. '') values.
|
156
156
|
# Hence we don't record it as a change if the value changes from nil to ''.
|
157
157
|
# If an old value of 0 is set to '' we want this to get changed to nil as otherwise it'll
|
158
158
|
# be typecast back to 0 (''.to_i => 0)
|
159
|
-
value = nil
|
159
|
+
value = nil
|
160
160
|
else
|
161
161
|
value = column.type_cast(value)
|
162
162
|
end
|
@@ -100,7 +100,7 @@ module ActiveRecord
|
|
100
100
|
end
|
101
101
|
|
102
102
|
class Scope
|
103
|
-
attr_reader :proxy_scope, :proxy_options
|
103
|
+
attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined
|
104
104
|
NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?).to_set
|
105
105
|
[].methods.each do |m|
|
106
106
|
unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s)
|
@@ -113,6 +113,9 @@ module ActiveRecord
|
|
113
113
|
def initialize(proxy_scope, options, &block)
|
114
114
|
[options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
|
115
115
|
extend Module.new(&block) if block_given?
|
116
|
+
unless Scope === proxy_scope
|
117
|
+
@current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods)
|
118
|
+
end
|
116
119
|
@proxy_scope, @proxy_options = proxy_scope, options.except(:extend)
|
117
120
|
end
|
118
121
|
|
@@ -168,7 +171,13 @@ module ActiveRecord
|
|
168
171
|
else
|
169
172
|
with_scope :find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {} do
|
170
173
|
method = :new if method == :build
|
171
|
-
|
174
|
+
if current_scoped_methods_when_defined
|
175
|
+
with_scope current_scoped_methods_when_defined do
|
176
|
+
proxy_scope.send(method, *args, &block)
|
177
|
+
end
|
178
|
+
else
|
179
|
+
proxy_scope.send(method, *args, &block)
|
180
|
+
end
|
172
181
|
end
|
173
182
|
end
|
174
183
|
end
|
@@ -198,6 +198,14 @@ module ActiveRecord
|
|
198
198
|
end
|
199
199
|
end
|
200
200
|
|
201
|
+
def columns(tbl_name, log_msg)
|
202
|
+
@columns ||= klass.connection.columns(tbl_name, log_msg)
|
203
|
+
end
|
204
|
+
|
205
|
+
def reset_column_information
|
206
|
+
@columns = nil
|
207
|
+
end
|
208
|
+
|
201
209
|
def check_validity!
|
202
210
|
end
|
203
211
|
|
@@ -147,7 +147,7 @@ module ActiveRecord
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def save_with_transactions! #:nodoc:
|
150
|
-
rollback_active_record_state! { transaction { save_without_transactions! } }
|
150
|
+
rollback_active_record_state! { self.class.transaction { save_without_transactions! } }
|
151
151
|
end
|
152
152
|
|
153
153
|
# Reset id and @new_record if the transaction rolls back.
|
@@ -175,7 +175,7 @@ module ActiveRecord
|
|
175
175
|
# instance.
|
176
176
|
def with_transaction_returning_status(method, *args)
|
177
177
|
status = nil
|
178
|
-
transaction do
|
178
|
+
self.class.transaction do
|
179
179
|
status = send(method, *args)
|
180
180
|
raise ActiveRecord::Rollback unless status
|
181
181
|
end
|
@@ -770,4 +770,15 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
770
770
|
end
|
771
771
|
end
|
772
772
|
end
|
773
|
+
|
774
|
+
def test_caching_of_columns
|
775
|
+
david = Developer.find(1)
|
776
|
+
# clear cache possibly created by other tests
|
777
|
+
david.projects.reset_column_information
|
778
|
+
assert_queries(0) { david.projects.columns; david.projects.columns }
|
779
|
+
# and again to verify that reset_column_information clears the cache correctly
|
780
|
+
david.projects.reset_column_information
|
781
|
+
assert_queries(0) { david.projects.columns; david.projects.columns }
|
782
|
+
end
|
783
|
+
|
773
784
|
end
|
@@ -29,6 +29,11 @@ class InnerJoinAssociationTest < ActiveRecord::TestCase
|
|
29
29
|
assert_match /INNER JOIN .?categories.? ON.*AND.*.?General.?.*TERMINATING_MARKER/, sql
|
30
30
|
end
|
31
31
|
|
32
|
+
def test_construct_finder_sql_applies_aliases_tables_on_association_conditions
|
33
|
+
result = Author.find(:all, :joins => [:thinking_posts, :welcome_posts])
|
34
|
+
assert_equal authors(:david), result.first
|
35
|
+
end
|
36
|
+
|
32
37
|
def test_construct_finder_sql_unpacks_nested_joins
|
33
38
|
sql = Author.send(:construct_finder_sql, :joins => {:posts => [[:comments]]})
|
34
39
|
assert_no_match /inner join.*inner join.*inner join/i, sql, "only two join clauses should be present"
|
@@ -2,9 +2,24 @@ require "cases/helper"
|
|
2
2
|
|
3
3
|
class MysqlConnectionTest < ActiveRecord::TestCase
|
4
4
|
def setup
|
5
|
+
super
|
5
6
|
@connection = ActiveRecord::Base.connection
|
6
7
|
end
|
7
8
|
|
9
|
+
def test_mysql_reconnect_attribute_after_connection_with_reconnect_true
|
10
|
+
run_without_connection do |orig_connection|
|
11
|
+
ActiveRecord::Base.establish_connection(orig_connection.merge({:reconnect => true}))
|
12
|
+
assert ActiveRecord::Base.connection.raw_connection.reconnect
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_mysql_reconnect_attribute_after_connection_with_reconnect_false
|
17
|
+
run_without_connection do |orig_connection|
|
18
|
+
ActiveRecord::Base.establish_connection(orig_connection.merge({:reconnect => false}))
|
19
|
+
assert !ActiveRecord::Base.connection.raw_connection.reconnect
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
8
23
|
def test_no_automatic_reconnection_after_timeout
|
9
24
|
assert @connection.active?
|
10
25
|
@connection.update('set @@wait_timeout=1')
|
@@ -27,4 +42,15 @@ class MysqlConnectionTest < ActiveRecord::TestCase
|
|
27
42
|
@connection.verify!
|
28
43
|
assert @connection.active?
|
29
44
|
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def run_without_connection
|
49
|
+
original_connection = ActiveRecord::Base.remove_connection
|
50
|
+
begin
|
51
|
+
yield original_connection
|
52
|
+
ensure
|
53
|
+
ActiveRecord::Base.establish_connection(original_connection)
|
54
|
+
end
|
55
|
+
end
|
30
56
|
end
|
data/test/cases/dirty_test.rb
CHANGED
@@ -58,7 +58,7 @@ class DirtyTest < ActiveRecord::TestCase
|
|
58
58
|
assert_equal parrot.name_change, parrot.title_change
|
59
59
|
end
|
60
60
|
|
61
|
-
def
|
61
|
+
def test_nullable_number_not_marked_as_changed_if_new_value_is_blank
|
62
62
|
pirate = Pirate.new
|
63
63
|
|
64
64
|
["", nil].each do |value|
|
@@ -68,6 +68,18 @@ class DirtyTest < ActiveRecord::TestCase
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
def test_nullable_integer_zero_to_string_zero_not_marked_as_changed
|
72
|
+
pirate = Pirate.new
|
73
|
+
pirate.parrot_id = 0
|
74
|
+
pirate.catchphrase = 'arrr'
|
75
|
+
assert pirate.save!
|
76
|
+
|
77
|
+
assert !pirate.changed?
|
78
|
+
|
79
|
+
pirate.parrot_id = '0'
|
80
|
+
assert !pirate.changed?
|
81
|
+
end
|
82
|
+
|
71
83
|
def test_zero_to_blank_marked_as_changed
|
72
84
|
pirate = Pirate.new
|
73
85
|
pirate.catchphrase = "Yarrrr, me hearties"
|
data/test/cases/helper.rb
CHANGED
@@ -31,7 +31,7 @@ rescue LoadError
|
|
31
31
|
end
|
32
32
|
|
33
33
|
ActiveRecord::Base.connection.class.class_eval do
|
34
|
-
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/]
|
34
|
+
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /SHOW FIELDS/]
|
35
35
|
|
36
36
|
def execute_with_query_record(sql, name = nil, &block)
|
37
37
|
$queries_executed ||= []
|
@@ -59,4 +59,4 @@ unless ENV['FIXTURE_DEBUG']
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
62
|
-
end
|
62
|
+
end
|
@@ -341,8 +341,10 @@ class NestedScopingTest < ActiveRecord::TestCase
|
|
341
341
|
def test_merged_scoped_find
|
342
342
|
poor_jamis = developers(:poor_jamis)
|
343
343
|
Developer.with_scope(:find => { :conditions => "salary < 100000" }) do
|
344
|
-
Developer.with_scope(:find => { :offset => 1 }) do
|
345
|
-
|
344
|
+
Developer.with_scope(:find => { :offset => 1, :order => 'id asc' }) do
|
345
|
+
assert_sql /ORDER BY id asc / do
|
346
|
+
assert_equal(poor_jamis, Developer.find(:first, :order => 'id asc'))
|
347
|
+
end
|
346
348
|
end
|
347
349
|
end
|
348
350
|
end
|
@@ -142,6 +142,15 @@ class NamedScopeTest < ActiveRecord::TestCase
|
|
142
142
|
assert_equal authors(:david).comments & Comment.containing_the_letter_e, authors(:david).comments.containing_the_letter_e
|
143
143
|
end
|
144
144
|
|
145
|
+
def test_named_scopes_honor_current_scopes_from_when_defined
|
146
|
+
assert !Post.ranked_by_comments.limit(5).empty?
|
147
|
+
assert !authors(:david).posts.ranked_by_comments.limit(5).empty?
|
148
|
+
assert_not_equal Post.ranked_by_comments.limit(5), authors(:david).posts.ranked_by_comments.limit(5)
|
149
|
+
assert_not_equal Post.top(5), authors(:david).posts.top(5)
|
150
|
+
assert_equal authors(:david).posts.ranked_by_comments.limit(5), authors(:david).posts.top(5)
|
151
|
+
assert_equal Post.ranked_by_comments.limit(5), Post.top(5)
|
152
|
+
end
|
153
|
+
|
145
154
|
def test_active_records_have_scope_named__all__
|
146
155
|
assert !Topic.find(:all).empty?
|
147
156
|
|
@@ -506,7 +506,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
|
|
506
506
|
|
507
507
|
# validates_length_of :is w/o mocha
|
508
508
|
|
509
|
-
def
|
509
|
+
def test_validates_length_of_is_finds_custom_model_key_translation
|
510
510
|
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
|
511
511
|
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
|
512
512
|
|
@@ -515,7 +515,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
|
|
515
515
|
assert_equal 'custom message', @topic.errors.on(:title)
|
516
516
|
end
|
517
517
|
|
518
|
-
def
|
518
|
+
def test_validates_length_of_is_finds_global_default_translation
|
519
519
|
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
|
520
520
|
|
521
521
|
Topic.validates_length_of :title, :is => 5
|
@@ -525,7 +525,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
|
|
525
525
|
|
526
526
|
# validates_uniqueness_of w/o mocha
|
527
527
|
|
528
|
-
def
|
528
|
+
def test_validates_length_of_is_finds_custom_model_key_translation
|
529
529
|
I18n.backend.store_translations 'en', :activerecord => {:errors => {:models => {:topic => {:attributes => {:title => {:wrong_length => 'custom message'}}}}}}
|
530
530
|
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
|
531
531
|
|
@@ -534,7 +534,7 @@ class ActiveRecordValidationsI18nTests < Test::Unit::TestCase
|
|
534
534
|
assert_equal 'custom message', @topic.errors.on(:title)
|
535
535
|
end
|
536
536
|
|
537
|
-
def
|
537
|
+
def test_validates_length_of_is_finds_global_default_translation
|
538
538
|
I18n.backend.store_translations 'en', :activerecord => {:errors => {:messages => {:wrong_length => 'global message'}}}
|
539
539
|
|
540
540
|
Topic.validates_length_of :title, :is => 5
|
@@ -0,0 +1,18 @@
|
|
1
|
+
print "Using Derby via JRuby, activerecord-jdbc-adapter and activerecord-jdbcderby-adapter\n"
|
2
|
+
require_dependency 'models/course'
|
3
|
+
require 'logger'
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
6
|
+
ActiveRecord::Base.configurations = {
|
7
|
+
'arunit' => {
|
8
|
+
:adapter => 'jdbcderby',
|
9
|
+
:database => 'activerecord_unittest'
|
10
|
+
},
|
11
|
+
'arunit2' => {
|
12
|
+
:adapter => 'jdbcderby',
|
13
|
+
:database => 'activerecord_unittest2'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
ActiveRecord::Base.establish_connection 'arunit'
|
18
|
+
Course.establish_connection 'arunit2'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
print "Using H2 via JRuby, activerecord-jdbc-adapter and activerecord-jdbch2-adapter\n"
|
2
|
+
require_dependency 'models/course'
|
3
|
+
require 'logger'
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
6
|
+
ActiveRecord::Base.configurations = {
|
7
|
+
'arunit' => {
|
8
|
+
:adapter => 'jdbch2',
|
9
|
+
:database => 'activerecord_unittest'
|
10
|
+
},
|
11
|
+
'arunit2' => {
|
12
|
+
:adapter => 'jdbch2',
|
13
|
+
:database => 'activerecord_unittest2'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
ActiveRecord::Base.establish_connection 'arunit'
|
18
|
+
Course.establish_connection 'arunit2'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
print "Using HSQLDB via JRuby, activerecord-jdbc-adapter and activerecord-jdbchsqldb-adapter\n"
|
2
|
+
require_dependency 'models/course'
|
3
|
+
require 'logger'
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
6
|
+
ActiveRecord::Base.configurations = {
|
7
|
+
'arunit' => {
|
8
|
+
:adapter => 'jdbchsqldb',
|
9
|
+
:database => 'activerecord_unittest'
|
10
|
+
},
|
11
|
+
'arunit2' => {
|
12
|
+
:adapter => 'jdbchsqldb',
|
13
|
+
:database => 'activerecord_unittest2'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
ActiveRecord::Base.establish_connection 'arunit'
|
18
|
+
Course.establish_connection 'arunit2'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
print "Using MySQL via JRuby, activerecord-jdbc-adapter and activerecord-jdbcmysql-adapter\n"
|
2
|
+
require_dependency 'models/course'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
6
|
+
|
7
|
+
# GRANT ALL PRIVILEGES ON activerecord_unittest.* to 'rails'@'localhost';
|
8
|
+
# GRANT ALL PRIVILEGES ON activerecord_unittest2.* to 'rails'@'localhost';
|
9
|
+
|
10
|
+
ActiveRecord::Base.configurations = {
|
11
|
+
'arunit' => {
|
12
|
+
:adapter => 'jdbcmysql',
|
13
|
+
:username => 'rails',
|
14
|
+
:encoding => 'utf8',
|
15
|
+
:database => 'activerecord_unittest',
|
16
|
+
},
|
17
|
+
'arunit2' => {
|
18
|
+
:adapter => 'jdbcmysql',
|
19
|
+
:username => 'rails',
|
20
|
+
:database => 'activerecord_unittest2'
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
ActiveRecord::Base.establish_connection 'arunit'
|
25
|
+
Course.establish_connection 'arunit2'
|
26
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
print "Using Postgrsql via JRuby, activerecord-jdbc-adapter and activerecord-postgresql-adapter\n"
|
2
|
+
require_dependency 'models/course'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
6
|
+
|
7
|
+
# createuser rails --createdb --no-superuser --no-createrole
|
8
|
+
# createdb -O rails activerecord_unittest
|
9
|
+
# createdb -O rails activerecord_unittest2
|
10
|
+
|
11
|
+
ActiveRecord::Base.configurations = {
|
12
|
+
'arunit' => {
|
13
|
+
:adapter => 'jdbcpostgresql',
|
14
|
+
:username => ENV['USER'] || 'rails',
|
15
|
+
:database => 'activerecord_unittest'
|
16
|
+
},
|
17
|
+
'arunit2' => {
|
18
|
+
:adapter => 'jdbcpostgresql',
|
19
|
+
:username => ENV['USER'] || 'rails',
|
20
|
+
:database => 'activerecord_unittest2'
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
ActiveRecord::Base.establish_connection 'arunit'
|
25
|
+
Course.establish_connection 'arunit2'
|
26
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
print "Using SQLite3 via JRuby, activerecord-jdbc-adapter and activerecord-jdbcsqlite3-adapter\n"
|
2
|
+
require_dependency 'models/course'
|
3
|
+
require 'logger'
|
4
|
+
ActiveRecord::Base.logger = Logger.new("debug.log")
|
5
|
+
|
6
|
+
class SqliteError < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
BASE_DIR = FIXTURES_ROOT
|
10
|
+
sqlite_test_db = "#{BASE_DIR}/fixture_database.sqlite3"
|
11
|
+
sqlite_test_db2 = "#{BASE_DIR}/fixture_database_2.sqlite3"
|
12
|
+
|
13
|
+
def make_connection(clazz, db_file)
|
14
|
+
ActiveRecord::Base.configurations = { clazz.name => { :adapter => 'jdbcsqlite3', :database => db_file, :timeout => 5000 } }
|
15
|
+
unless File.exist?(db_file)
|
16
|
+
puts "SQLite3 database not found at #{db_file}. Rebuilding it."
|
17
|
+
sqlite_command = %Q{sqlite3 "#{db_file}" "create table a (a integer); drop table a;"}
|
18
|
+
puts "Executing '#{sqlite_command}'"
|
19
|
+
raise SqliteError.new("Seems that there is no sqlite3 executable available") unless system(sqlite_command)
|
20
|
+
end
|
21
|
+
clazz.establish_connection(clazz.name)
|
22
|
+
end
|
23
|
+
|
24
|
+
make_connection(ActiveRecord::Base, sqlite_test_db)
|
25
|
+
make_connection(Course, sqlite_test_db2)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/test/models/author.rb
CHANGED
@@ -24,6 +24,8 @@ class Author < ActiveRecord::Base
|
|
24
24
|
has_many :comments_with_order_and_conditions, :through => :posts, :source => :comments, :order => 'comments.body', :conditions => "comments.body like 'Thank%'"
|
25
25
|
has_many :comments_with_include, :through => :posts, :source => :comments, :include => :post
|
26
26
|
|
27
|
+
has_many :thinking_posts, :class_name => 'Post', :conditions => { :title => 'So I was thinking' }
|
28
|
+
has_many :welcome_posts, :class_name => 'Post', :conditions => { :title => 'Welcome to the weblog' }
|
27
29
|
|
28
30
|
has_many :comments_desc, :through => :posts, :source => :comments, :order => 'comments.id DESC'
|
29
31
|
has_many :limited_comments, :through => :posts, :source => :comments, :limit => 1
|
data/test/models/post.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class Post < ActiveRecord::Base
|
2
2
|
named_scope :containing_the_letter_a, :conditions => "body LIKE '%a%'"
|
3
|
+
named_scope :ranked_by_comments, :order => "comments_count DESC"
|
4
|
+
named_scope :limit, lambda {|limit| {:limit => limit} }
|
3
5
|
named_scope :with_authors_at_address, lambda { |address| {
|
4
6
|
:conditions => [ 'authors.author_address_id = ?', address.id ],
|
5
7
|
:joins => 'JOIN authors ON authors.id = posts.author_id'
|
@@ -62,6 +64,10 @@ class Post < ActiveRecord::Base
|
|
62
64
|
:before_remove => lambda {|owner, reader| log(:removed, :before, reader.first_name) },
|
63
65
|
:after_remove => lambda {|owner, reader| log(:removed, :after, reader.first_name) }
|
64
66
|
|
67
|
+
def self.top(limit)
|
68
|
+
ranked_by_comments.limit(limit)
|
69
|
+
end
|
70
|
+
|
65
71
|
def self.reset_log
|
66
72
|
@log = []
|
67
73
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
@@ -9,7 +9,7 @@ autorequire: active_record
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-09-28 00:00:00 +13:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - "="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 2.2.
|
23
|
+
version: 2.2.3
|
24
24
|
version:
|
25
25
|
description: Implements the ActiveRecord pattern (Fowler, PoEAA) for ORM. It ties database tables and classes together for business objects, like Customer or Subscription, that can find, save, and destroy themselves without resorting to manual SQL.
|
26
26
|
email: david@loudthinking.com
|
@@ -36,10 +36,8 @@ files:
|
|
36
36
|
- README
|
37
37
|
- RUNNING_UNIT_TESTS
|
38
38
|
- CHANGELOG
|
39
|
-
- lib/active_record
|
40
39
|
- lib/active_record/aggregations.rb
|
41
40
|
- lib/active_record/association_preload.rb
|
42
|
-
- lib/active_record/associations
|
43
41
|
- lib/active_record/associations/association_collection.rb
|
44
42
|
- lib/active_record/associations/association_proxy.rb
|
45
43
|
- lib/active_record/associations/belongs_to_association.rb
|
@@ -54,8 +52,6 @@ files:
|
|
54
52
|
- lib/active_record/base.rb
|
55
53
|
- lib/active_record/calculations.rb
|
56
54
|
- lib/active_record/callbacks.rb
|
57
|
-
- lib/active_record/connection_adapters
|
58
|
-
- lib/active_record/connection_adapters/abstract
|
59
55
|
- lib/active_record/connection_adapters/abstract/connection_pool.rb
|
60
56
|
- lib/active_record/connection_adapters/abstract/connection_specification.rb
|
61
57
|
- lib/active_record/connection_adapters/abstract/database_statements.rb
|
@@ -72,9 +68,7 @@ files:
|
|
72
68
|
- lib/active_record/dynamic_finder_match.rb
|
73
69
|
- lib/active_record/fixtures.rb
|
74
70
|
- lib/active_record/i18n_interpolation_deprecation.rb
|
75
|
-
- lib/active_record/locale
|
76
71
|
- lib/active_record/locale/en.yml
|
77
|
-
- lib/active_record/locking
|
78
72
|
- lib/active_record/locking/optimistic.rb
|
79
73
|
- lib/active_record/locking/pessimistic.rb
|
80
74
|
- lib/active_record/migration.rb
|
@@ -85,7 +79,6 @@ files:
|
|
85
79
|
- lib/active_record/schema.rb
|
86
80
|
- lib/active_record/schema_dumper.rb
|
87
81
|
- lib/active_record/serialization.rb
|
88
|
-
- lib/active_record/serializers
|
89
82
|
- lib/active_record/serializers/json_serializer.rb
|
90
83
|
- lib/active_record/serializers/xml_serializer.rb
|
91
84
|
- lib/active_record/test_case.rb
|
@@ -95,17 +88,14 @@ files:
|
|
95
88
|
- lib/active_record/version.rb
|
96
89
|
- lib/active_record.rb
|
97
90
|
- lib/activerecord.rb
|
98
|
-
- test/assets
|
99
91
|
- test/assets/example.log
|
100
92
|
- test/assets/flowers.jpg
|
101
|
-
- test/cases
|
102
93
|
- test/cases/aaa_create_tables_test.rb
|
103
94
|
- test/cases/active_schema_test_mysql.rb
|
104
95
|
- test/cases/active_schema_test_postgresql.rb
|
105
96
|
- test/cases/adapter_test.rb
|
106
97
|
- test/cases/aggregations_test.rb
|
107
98
|
- test/cases/ar_schema_test.rb
|
108
|
-
- test/cases/associations
|
109
99
|
- test/cases/associations/belongs_to_associations_test.rb
|
110
100
|
- test/cases/associations/callbacks_test.rb
|
111
101
|
- test/cases/associations/cascaded_eager_loading_test.rb
|
@@ -177,31 +167,24 @@ files:
|
|
177
167
|
- test/cases/validations_test.rb
|
178
168
|
- test/cases/xml_serialization_test.rb
|
179
169
|
- test/config.rb
|
180
|
-
- test/connections
|
181
|
-
- test/connections/
|
170
|
+
- test/connections/jdbc_jdbcderby/connection.rb
|
171
|
+
- test/connections/jdbc_jdbch2/connection.rb
|
172
|
+
- test/connections/jdbc_jdbchsqldb/connection.rb
|
173
|
+
- test/connections/jdbc_jdbcmysql/connection.rb
|
174
|
+
- test/connections/jdbc_jdbcpostgresql/connection.rb
|
175
|
+
- test/connections/jdbc_jdbcsqlite3/connection.rb
|
182
176
|
- test/connections/native_db2/connection.rb
|
183
|
-
- test/connections/native_firebird
|
184
177
|
- test/connections/native_firebird/connection.rb
|
185
|
-
- test/connections/native_frontbase
|
186
178
|
- test/connections/native_frontbase/connection.rb
|
187
|
-
- test/connections/native_mysql
|
188
179
|
- test/connections/native_mysql/connection.rb
|
189
|
-
- test/connections/native_openbase
|
190
180
|
- test/connections/native_openbase/connection.rb
|
191
|
-
- test/connections/native_oracle
|
192
181
|
- test/connections/native_oracle/connection.rb
|
193
|
-
- test/connections/native_postgresql
|
194
182
|
- test/connections/native_postgresql/connection.rb
|
195
|
-
- test/connections/native_sqlite
|
196
183
|
- test/connections/native_sqlite/connection.rb
|
197
|
-
- test/connections/native_sqlite3
|
198
184
|
- test/connections/native_sqlite3/connection.rb
|
199
185
|
- test/connections/native_sqlite3/in_memory_connection.rb
|
200
|
-
- test/connections/native_sybase
|
201
186
|
- test/connections/native_sybase/connection.rb
|
202
|
-
- test/fixtures
|
203
187
|
- test/fixtures/accounts.yml
|
204
|
-
- test/fixtures/all
|
205
188
|
- test/fixtures/all/developers.yml
|
206
189
|
- test/fixtures/all/people.csv
|
207
190
|
- test/fixtures/all/tasks.yml
|
@@ -210,9 +193,7 @@ files:
|
|
210
193
|
- test/fixtures/authors.yml
|
211
194
|
- test/fixtures/binaries.yml
|
212
195
|
- test/fixtures/books.yml
|
213
|
-
- test/fixtures/categories
|
214
196
|
- test/fixtures/categories/special_categories.yml
|
215
|
-
- test/fixtures/categories/subsubdir
|
216
197
|
- test/fixtures/categories/subsubdir/arbitrary_filename.yml
|
217
198
|
- test/fixtures/categories.yml
|
218
199
|
- test/fixtures/categories_ordered.yml
|
@@ -228,7 +209,9 @@ files:
|
|
228
209
|
- test/fixtures/developers_projects.yml
|
229
210
|
- test/fixtures/edges.yml
|
230
211
|
- test/fixtures/entrants.yml
|
212
|
+
- test/fixtures/fixture_database.sqlite
|
231
213
|
- test/fixtures/fixture_database.sqlite3
|
214
|
+
- test/fixtures/fixture_database_2.sqlite
|
232
215
|
- test/fixtures/fixture_database_2.sqlite3
|
233
216
|
- test/fixtures/fk_test_has_fk.yml
|
234
217
|
- test/fixtures/fk_test_has_pk.yml
|
@@ -243,10 +226,7 @@ files:
|
|
243
226
|
- test/fixtures/mixed_case_monkeys.yml
|
244
227
|
- test/fixtures/mixins.yml
|
245
228
|
- test/fixtures/movies.yml
|
246
|
-
- test/fixtures/naked
|
247
|
-
- test/fixtures/naked/csv
|
248
229
|
- test/fixtures/naked/csv/accounts.csv
|
249
|
-
- test/fixtures/naked/yml
|
250
230
|
- test/fixtures/naked/yml/accounts.yml
|
251
231
|
- test/fixtures/naked/yml/companies.yml
|
252
232
|
- test/fixtures/naked/yml/courses.yml
|
@@ -262,7 +242,6 @@ files:
|
|
262
242
|
- test/fixtures/projects.yml
|
263
243
|
- test/fixtures/readers.yml
|
264
244
|
- test/fixtures/references.yml
|
265
|
-
- test/fixtures/reserved_words
|
266
245
|
- test/fixtures/reserved_words/distinct.yml
|
267
246
|
- test/fixtures/reserved_words/distincts_selects.yml
|
268
247
|
- test/fixtures/reserved_words/group.yml
|
@@ -279,39 +258,27 @@ files:
|
|
279
258
|
- test/fixtures/treasures.yml
|
280
259
|
- test/fixtures/vertices.yml
|
281
260
|
- test/fixtures/warehouse-things.yml
|
282
|
-
- test/migrations
|
283
|
-
- test/migrations/broken
|
284
261
|
- test/migrations/broken/100_migration_that_raises_exception.rb
|
285
|
-
- test/migrations/decimal
|
286
262
|
- test/migrations/decimal/1_give_me_big_numbers.rb
|
287
|
-
- test/migrations/duplicate
|
288
263
|
- test/migrations/duplicate/1_people_have_last_names.rb
|
289
264
|
- test/migrations/duplicate/2_we_need_reminders.rb
|
290
265
|
- test/migrations/duplicate/3_foo.rb
|
291
266
|
- test/migrations/duplicate/3_innocent_jointable.rb
|
292
|
-
- test/migrations/duplicate_names
|
293
267
|
- test/migrations/duplicate_names/20080507052938_chunky.rb
|
294
268
|
- test/migrations/duplicate_names/20080507053028_chunky.rb
|
295
|
-
- test/migrations/interleaved
|
296
|
-
- test/migrations/interleaved/pass_1
|
297
269
|
- test/migrations/interleaved/pass_1/3_innocent_jointable.rb
|
298
|
-
- test/migrations/interleaved/pass_2
|
299
270
|
- test/migrations/interleaved/pass_2/1_people_have_last_names.rb
|
300
271
|
- test/migrations/interleaved/pass_2/3_innocent_jointable.rb
|
301
|
-
- test/migrations/interleaved/pass_3
|
302
272
|
- test/migrations/interleaved/pass_3/1_people_have_last_names.rb
|
303
273
|
- test/migrations/interleaved/pass_3/2_i_raise_on_down.rb
|
304
274
|
- test/migrations/interleaved/pass_3/3_innocent_jointable.rb
|
305
|
-
- test/migrations/missing
|
306
275
|
- test/migrations/missing/1000_people_have_middle_names.rb
|
307
276
|
- test/migrations/missing/1_people_have_last_names.rb
|
308
277
|
- test/migrations/missing/3_we_need_reminders.rb
|
309
278
|
- test/migrations/missing/4_innocent_jointable.rb
|
310
|
-
- test/migrations/valid
|
311
279
|
- test/migrations/valid/1_people_have_last_names.rb
|
312
280
|
- test/migrations/valid/2_we_need_reminders.rb
|
313
281
|
- test/migrations/valid/3_innocent_jointable.rb
|
314
|
-
- test/models
|
315
282
|
- test/models/author.rb
|
316
283
|
- test/models/auto_id.rb
|
317
284
|
- test/models/binary.rb
|
@@ -370,7 +337,6 @@ files:
|
|
370
337
|
- test/models/treasure.rb
|
371
338
|
- test/models/vertex.rb
|
372
339
|
- test/models/warehouse_thing.rb
|
373
|
-
- test/schema
|
374
340
|
- test/schema/mysql_specific_schema.rb
|
375
341
|
- test/schema/postgresql_specific_schema.rb
|
376
342
|
- test/schema/schema.rb
|
@@ -379,6 +345,8 @@ files:
|
|
379
345
|
- examples/associations.png
|
380
346
|
has_rdoc: true
|
381
347
|
homepage: http://www.rubyonrails.org
|
348
|
+
licenses: []
|
349
|
+
|
382
350
|
post_install_message:
|
383
351
|
rdoc_options:
|
384
352
|
- --main
|
@@ -400,9 +368,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
400
368
|
requirements: []
|
401
369
|
|
402
370
|
rubyforge_project: activerecord
|
403
|
-
rubygems_version: 1.3.
|
371
|
+
rubygems_version: 1.3.2
|
404
372
|
signing_key:
|
405
|
-
specification_version:
|
373
|
+
specification_version: 3
|
406
374
|
summary: Implements the ActiveRecord pattern for ORM.
|
407
375
|
test_files: []
|
408
376
|
|