activerecord 1.6.0 → 1.7.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.
- data/CHANGELOG +78 -0
- data/README +20 -29
- data/RUNNING_UNIT_TESTS +1 -2
- data/examples/validation.rb +0 -3
- data/install.rb +3 -16
- data/lib/active_record.rb +11 -4
- data/lib/active_record/aggregations.rb +2 -2
- data/lib/active_record/associations.rb +8 -8
- data/lib/active_record/associations/association_collection.rb +1 -1
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -1
- data/lib/active_record/base.rb +117 -43
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/connection_adapters/abstract_adapter.rb +7 -14
- data/lib/active_record/connection_adapters/db2_adapter.rb +33 -22
- data/lib/active_record/connection_adapters/mysql_adapter.rb +74 -33
- data/lib/active_record/connection_adapters/oci_adapter.rb +265 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +23 -3
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +13 -4
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +158 -67
- data/lib/active_record/deprecated_associations.rb +4 -4
- data/lib/active_record/fixtures.rb +12 -5
- data/lib/active_record/locking.rb +22 -22
- data/lib/active_record/observer.rb +6 -3
- data/lib/active_record/timestamp.rb +15 -5
- data/lib/active_record/transactions.rb +4 -4
- data/lib/active_record/validations.rb +272 -189
- data/lib/active_record/wrappings.rb +2 -2
- data/rakefile +17 -2
- data/test/aaa_create_tables_test.rb +58 -0
- data/test/abstract_unit.rb +3 -2
- data/test/aggregations_test.rb +0 -1
- data/test/associations_test.rb +27 -28
- data/test/base_test.rb +74 -2
- data/test/binary_test.rb +6 -2
- data/test/class_inheritable_attributes_test.rb +1 -1
- data/test/column_alias_test.rb +9 -2
- data/test/connections/native_oci/connection.rb +25 -0
- data/test/connections/native_sqlite/connection.rb +4 -1
- data/test/connections/native_sqlite3/connection.rb +4 -2
- data/test/deprecated_associations_test.rb +4 -5
- data/test/finder_test.rb +20 -4
- data/test/fixtures/db_definitions/create_oracle_db.bat +5 -0
- data/test/fixtures/db_definitions/create_oracle_db.sh +5 -0
- data/test/fixtures/db_definitions/db2.drop.sql +18 -0
- data/test/fixtures/db_definitions/db2.sql +1 -0
- data/test/fixtures/db_definitions/db22.drop.sql +2 -0
- data/test/fixtures/db_definitions/db22.sql +1 -0
- data/test/fixtures/db_definitions/drop_oracle_tables.sql +35 -0
- data/test/fixtures/db_definitions/drop_oracle_tables2.sql +3 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +18 -0
- data/test/fixtures/db_definitions/mysql.sql +2 -1
- data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql2.sql +1 -0
- data/test/fixtures/db_definitions/oci.drop.sql +18 -0
- data/test/fixtures/db_definitions/oci.sql +167 -0
- data/test/fixtures/db_definitions/oci2.drop.sql +2 -0
- data/test/fixtures/db_definitions/oci2.sql +6 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +18 -0
- data/test/fixtures/db_definitions/postgresql.sql +2 -1
- data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/postgresql2.sql +2 -1
- data/test/fixtures/db_definitions/sqlite.drop.sql +18 -0
- data/test/fixtures/db_definitions/sqlite.sql +2 -1
- data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite2.sql +1 -0
- data/test/fixtures/db_definitions/sqlserver.drop.sql +18 -0
- data/test/fixtures/db_definitions/sqlserver.sql +1 -0
- data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver2.sql +1 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/topics.yml +3 -3
- data/test/lifecycle_test.rb +0 -1
- data/test/modules_test.rb +0 -1
- data/test/reflection_test.rb +0 -1
- data/test/validations_test.rb +229 -41
- metadata +36 -28
- data/dev-utils/eval_debugger.rb +0 -14
- data/lib/active_record/support/binding_of_caller.rb +0 -83
- data/lib/active_record/support/breakpoint.rb +0 -518
- data/lib/active_record/support/class_attribute_accessors.rb +0 -57
- data/lib/active_record/support/class_inheritable_attributes.rb +0 -117
- data/lib/active_record/support/clean_logger.rb +0 -10
- data/lib/active_record/support/core_ext.rb +0 -1
- data/lib/active_record/support/core_ext/hash.rb +0 -5
- data/lib/active_record/support/core_ext/hash/keys.rb +0 -35
- data/lib/active_record/support/core_ext/numeric.rb +0 -7
- data/lib/active_record/support/core_ext/numeric/bytes.rb +0 -33
- data/lib/active_record/support/core_ext/numeric/time.rb +0 -59
- data/lib/active_record/support/core_ext/object_and_class.rb +0 -24
- data/lib/active_record/support/core_ext/string.rb +0 -5
- data/lib/active_record/support/core_ext/string/inflections.rb +0 -45
- data/lib/active_record/support/dependencies.rb +0 -63
- data/lib/active_record/support/inflector.rb +0 -84
- data/lib/active_record/support/misc.rb +0 -8
- data/lib/active_record/support/module_attribute_accessors.rb +0 -57
@@ -24,21 +24,37 @@ module ActiveRecord
|
|
24
24
|
username = config[:username].to_s
|
25
25
|
password = config[:password].to_s
|
26
26
|
|
27
|
+
schema_order = config[:schema_order]
|
28
|
+
|
27
29
|
if config.has_key?(:database)
|
28
30
|
database = config[:database]
|
29
31
|
else
|
30
32
|
raise ArgumentError, "No database specified. Missing argument: database."
|
31
33
|
end
|
32
34
|
|
33
|
-
ConnectionAdapters::PostgreSQLAdapter.new(
|
35
|
+
pga = ConnectionAdapters::PostgreSQLAdapter.new(
|
34
36
|
PGconn.connect(host, port, "", "", database, username, password), logger
|
35
37
|
)
|
38
|
+
|
39
|
+
pga.execute("SET search_path TO #{schema_order}") if schema_order
|
40
|
+
|
41
|
+
pga
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
39
45
|
module ConnectionAdapters
|
40
|
-
|
41
|
-
|
46
|
+
# The PostgreSQL adapter works both with the C-based (http://www.postgresql.jp/interfaces/ruby/) and the Ruby-base
|
47
|
+
# (available both as gem and from http://rubyforge.org/frs/?group_id=234&release_id=1145) drivers.
|
48
|
+
#
|
49
|
+
# Options:
|
50
|
+
#
|
51
|
+
# * <tt>:host</tt> -- Defaults to localhost
|
52
|
+
# * <tt>:port</tt> -- Defaults to 5432
|
53
|
+
# * <tt>:username</tt> -- Defaults to nothing
|
54
|
+
# * <tt>:password</tt> -- Defaults to nothing
|
55
|
+
# * <tt>:database</tt> -- The name of the database. No default, must be provided.
|
56
|
+
# * <tt>:schema_order</tt> -- An optional schema order string that is using in a SET search_path TO <schema_order> call on connection.
|
57
|
+
class PostgreSQLAdapter < AbstractAdapter
|
42
58
|
def select_all(sql, name = nil)
|
43
59
|
select(sql, name)
|
44
60
|
end
|
@@ -89,6 +105,10 @@ module ActiveRecord
|
|
89
105
|
return "\"#{name}\""
|
90
106
|
end
|
91
107
|
|
108
|
+
def adapter_name()
|
109
|
+
'PostgreSQL'
|
110
|
+
end
|
111
|
+
|
92
112
|
private
|
93
113
|
def last_insert_id(table, column = "id")
|
94
114
|
sequence_name = "#{table}_#{column || 'id'}_seq"
|
@@ -59,9 +59,8 @@ module ActiveRecord
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
module ConnectionAdapters
|
63
|
-
|
64
|
-
class SQLiteColumn < Column
|
62
|
+
module ConnectionAdapters #:nodoc:
|
63
|
+
class SQLiteColumn < Column #:nodoc:
|
65
64
|
def string_to_binary(value)
|
66
65
|
value.gsub(/(\0|\%)/) do
|
67
66
|
case $1
|
@@ -81,7 +80,13 @@ module ActiveRecord
|
|
81
80
|
end
|
82
81
|
end
|
83
82
|
|
84
|
-
|
83
|
+
# The SQLite adapter works with both the 2.x and 3.x series of SQLite with the sqlite-ruby drivers (available both as gems and
|
84
|
+
# from http://rubyforge.org/projects/sqlite-ruby/).
|
85
|
+
#
|
86
|
+
# Options:
|
87
|
+
#
|
88
|
+
# * <tt>:dbfile</tt> -- Path to the database file.
|
89
|
+
class SQLiteAdapter < AbstractAdapter
|
85
90
|
def execute(sql, name = nil)
|
86
91
|
log(sql, name) { @connection.execute(sql) }
|
87
92
|
end
|
@@ -141,6 +146,10 @@ module ActiveRecord
|
|
141
146
|
return "'#{name}'"
|
142
147
|
end
|
143
148
|
|
149
|
+
def adapter_name()
|
150
|
+
'SQLite'
|
151
|
+
end
|
152
|
+
|
144
153
|
protected
|
145
154
|
def table_structure(table_name)
|
146
155
|
execute "PRAGMA table_info(#{table_name})"
|
@@ -5,30 +5,12 @@ require 'active_record/connection_adapters/abstract_adapter'
|
|
5
5
|
# Author: Joey Gibson <joey@joeygibson.com>
|
6
6
|
# Date: 10/14/2004
|
7
7
|
#
|
8
|
-
# REQUIREMENTS:
|
9
|
-
#
|
10
|
-
# This adapter will ONLY work on Windows systems, since it relies on Win32OLE, which,
|
11
|
-
# to my knowledge, is only available on Window.
|
12
|
-
#
|
13
|
-
# It relies on the ADO support in the DBI module. If you are using the
|
14
|
-
# one-click installer of Ruby, then you already have DBI installed, but
|
15
|
-
# the ADO module is *NOT* installed. You will need to get the latest
|
16
|
-
# source distribution of Ruby-DBI from http://ruby-dbi.sourceforge.net/
|
17
|
-
# unzip it, and copy the file src/lib/dbd_ado/ADO.rb to
|
18
|
-
# X:/Ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb (you will need to create
|
19
|
-
# the ADO directory). Once you've installed that file, you are ready to go.
|
20
|
-
#
|
21
|
-
# This module uses the ADO-style DSNs for connection. For example:
|
22
|
-
# "DBI:ADO:Provider=SQLOLEDB;Data Source=(local);Initial Catalog=test;User Id=sa;Password=password;"
|
23
|
-
# with User Id replaced with your proper login, and Password with your
|
24
|
-
# password.
|
25
|
-
#
|
26
8
|
# I have tested this code on a WindowsXP Pro SP1 system,
|
27
9
|
# ruby 1.8.2 (2004-07-29) [i386-mswin32], SQL Server 2000.
|
28
10
|
#
|
29
11
|
module ActiveRecord
|
30
12
|
class Base
|
31
|
-
def self.sqlserver_connection(config)
|
13
|
+
def self.sqlserver_connection(config) #:nodoc:
|
32
14
|
require_library_or_gem 'dbi' unless self.class.const_defined?(:DBI)
|
33
15
|
|
34
16
|
symbolize_strings_in_hash(config)
|
@@ -52,58 +34,128 @@ module ActiveRecord
|
|
52
34
|
|
53
35
|
module ConnectionAdapters
|
54
36
|
class ColumnWithIdentity < Column# :nodoc:
|
55
|
-
attr_reader :identity
|
37
|
+
attr_reader :identity, :scale
|
56
38
|
|
57
|
-
def initialize(name, default, sql_type = nil, is_identity = false)
|
39
|
+
def initialize(name, default, sql_type = nil, is_identity = false, scale_value = 0)
|
58
40
|
super(name, default, sql_type)
|
59
41
|
|
42
|
+
@scale = scale_value
|
60
43
|
@identity = is_identity
|
44
|
+
end
|
45
|
+
|
46
|
+
def binary_to_string(value)
|
47
|
+
value
|
48
|
+
end
|
49
|
+
|
50
|
+
def string_to_binary(value)
|
51
|
+
value
|
52
|
+
end
|
53
|
+
|
54
|
+
def simplified_type(field_type)
|
55
|
+
case field_type
|
56
|
+
when /int/i
|
57
|
+
:integer
|
58
|
+
when /float|double|decimal|numeric/i
|
59
|
+
if @scale == 0
|
60
|
+
:integer
|
61
|
+
else
|
62
|
+
:float
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
when /datetime/i
|
66
|
+
:datetime
|
67
|
+
when /timestamp/i
|
68
|
+
:timestamp
|
69
|
+
when /time/i
|
70
|
+
:time
|
71
|
+
when /date/i
|
72
|
+
:date
|
73
|
+
when /clob|text|ntext/i
|
74
|
+
:text
|
75
|
+
when /blob|binary|image/i
|
76
|
+
:binary
|
77
|
+
when /char|string/i
|
78
|
+
:string
|
79
|
+
when /boolean|bit/i
|
80
|
+
:boolean
|
81
|
+
end
|
61
82
|
end
|
62
|
-
end
|
63
83
|
|
64
|
-
|
65
|
-
|
66
|
-
|
84
|
+
def string_to_time(string)
|
85
|
+
return string if string.is_a?(Time)
|
86
|
+
time_array = ParseDate.parsedate(string, true)
|
87
|
+
time_array.each_index do |i|
|
88
|
+
case i
|
89
|
+
when 0
|
90
|
+
time_array[i] = time_array[i].nil? ? "2000" : time_array[i].to_s
|
91
|
+
when 1
|
92
|
+
time_array[i] = time_array[i].nil? ? "Jan" : time_array[i].to_s
|
93
|
+
when 2
|
94
|
+
time_array[i] = time_array[i].nil? ? "1" : time_array[i].to_s
|
95
|
+
when 3
|
96
|
+
time_array[i] = time_array[i].nil? ? "0" : time_array[i].to_s
|
97
|
+
when 4
|
98
|
+
time_array[i] = time_array[i].nil? ? "0" : time_array[i].to_s
|
99
|
+
when 5
|
100
|
+
time_array[i] = time_array[i].nil? ? "0" : time_array[i].to_s
|
101
|
+
end
|
102
|
+
end
|
103
|
+
# treat 0000-00-00 00:00:00 as nil
|
104
|
+
Time.send(Base.default_timezone, *time_array) rescue nil
|
67
105
|
end
|
68
106
|
|
107
|
+
end
|
108
|
+
|
109
|
+
# This adapter will ONLY work on Windows systems, since it relies on Win32OLE, which,
|
110
|
+
# to my knowledge, is only available on Window.
|
111
|
+
#
|
112
|
+
# It relies on the ADO support in the DBI module. If you are using the
|
113
|
+
# one-click installer of Ruby, then you already have DBI installed, but
|
114
|
+
# the ADO module is *NOT* installed. You will need to get the latest
|
115
|
+
# source distribution of Ruby-DBI from http://ruby-dbi.sourceforge.net/
|
116
|
+
# unzip it, and copy the file <tt>src/lib/dbd_ado/ADO.rb</tt> to
|
117
|
+
# <tt>X:/Ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb</tt> (you will need to create
|
118
|
+
# the ADO directory). Once you've installed that file, you are ready to go.
|
119
|
+
#
|
120
|
+
# Options:
|
121
|
+
#
|
122
|
+
# * <tt>:host</tt> -- Defaults to localhost
|
123
|
+
# * <tt>:username</tt> -- Defaults to sa
|
124
|
+
# * <tt>:password</tt> -- Defaults to nothing
|
125
|
+
# * <tt>:database</tt> -- The name of the database. No default, must be provided.
|
126
|
+
class SQLServerAdapter < AbstractAdapter
|
69
127
|
def select_all(sql, name = nil)
|
128
|
+
add_limit!(sql, nil)
|
70
129
|
select(sql, name)
|
71
130
|
end
|
72
131
|
|
73
132
|
def select_one(sql, name = nil)
|
133
|
+
add_limit!(sql, nil)
|
74
134
|
result = select(sql, name)
|
75
135
|
result.nil? ? nil : result.first
|
76
136
|
end
|
77
137
|
|
78
138
|
def columns(table_name, name = nil)
|
79
139
|
sql = <<EOL
|
80
|
-
SELECT
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
140
|
+
SELECT
|
141
|
+
COLUMN_NAME as ColName,
|
142
|
+
COLUMN_DEFAULT as DefaultValue,
|
143
|
+
DATA_TYPE as ColType,
|
144
|
+
COL_LENGTH('#{table_name}', COLUMN_NAME) as Length,
|
145
|
+
COLUMNPROPERTY(OBJECT_ID('#{table_name}'), COLUMN_NAME, 'IsIdentity') as IsIdentity,
|
146
|
+
NUMERIC_SCALE as Scale
|
147
|
+
FROM INFORMATION_SCHEMA.columns
|
148
|
+
WHERE TABLE_NAME = '#{table_name}'
|
88
149
|
EOL
|
89
|
-
columns = []
|
90
|
-
|
91
|
-
log(sql, name, @connection) do |conn|
|
92
|
-
conn.select_all(sql) do |row|
|
93
|
-
default_value = row[:DefaultValue]
|
94
150
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
columns << col
|
105
|
-
end
|
106
|
-
end
|
151
|
+
result = nil
|
152
|
+
# Uncomment if you want to have the Columns select statment logged.
|
153
|
+
# Personnally, I think it adds unneccessary SQL statement bloat to the log.
|
154
|
+
# If you do uncomment, make sure to comment the "result" line that follows
|
155
|
+
log(sql, name, @connection) { |conn| result = conn.select_all(sql) }
|
156
|
+
#result = @connection.select_all(sql)
|
157
|
+
columns = []
|
158
|
+
result.each { |field| columns << ColumnWithIdentity.new(field[:ColName], field[:DefaultValue].to_s.gsub!(/[()\']/,"") =~ /null/ ? nil : field[:DefaultValue], "#{field[:ColType]}(#{field[:Length]})", field[:IsIdentity] == 1 ? true : false, field[:Scale]) }
|
107
159
|
|
108
160
|
columns
|
109
161
|
end
|
@@ -144,16 +196,6 @@ EOL
|
|
144
196
|
end
|
145
197
|
end
|
146
198
|
|
147
|
-
def execute(sql, name = nil)
|
148
|
-
if sql =~ /^INSERT/i
|
149
|
-
insert(sql, name)
|
150
|
-
else
|
151
|
-
log(sql, name, @connection) do |conn|
|
152
|
-
conn.execute(sql)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
199
|
def update(sql, name = nil)
|
158
200
|
execute(sql, name)
|
159
201
|
affected_rows(name)
|
@@ -185,6 +227,47 @@ EOL
|
|
185
227
|
end
|
186
228
|
end
|
187
229
|
|
230
|
+
def quote(value, column = nil)
|
231
|
+
case value
|
232
|
+
when String
|
233
|
+
if column && column.type == :binary
|
234
|
+
"'#{quote_string(column.string_to_binary(value))}'"
|
235
|
+
else
|
236
|
+
"'#{quote_string(value)}'"
|
237
|
+
end
|
238
|
+
when NilClass then "NULL"
|
239
|
+
when TrueClass then (column && column.type == :boolean ? "'t'" : "1")
|
240
|
+
when FalseClass then (column && column.type == :boolean ? "'f'" : "0")
|
241
|
+
when Float, Fixnum, Bignum then value.to_s
|
242
|
+
when Date then "'#{value.to_s}'"
|
243
|
+
when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
|
244
|
+
else "'#{quote_string(value.to_yaml)}'"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def quote_string(s)
|
249
|
+
s.gsub(/\'/, "''")
|
250
|
+
end
|
251
|
+
|
252
|
+
def quote_column_name(name)
|
253
|
+
"[#{name}]"
|
254
|
+
end
|
255
|
+
|
256
|
+
def add_limit!(sql, limit)
|
257
|
+
if sql =~ /LIMIT/i
|
258
|
+
limit = sql.slice!(/LIMIT.*/).gsub(/LIMIT.(.*)$/, '\1')
|
259
|
+
end
|
260
|
+
if !limit.nil?
|
261
|
+
limit_amount = limit.to_s.include?("OFFSET") ? get_offset_amount(limit) : Array.new([limit])
|
262
|
+
order_by = sql.include?("ORDER BY") ? get_order_by(sql.sub(/.*ORDER\sBY./, "")) : nil
|
263
|
+
if limit_amount.size == 2
|
264
|
+
sql.gsub!(/SELECT/i, "SELECT * FROM ( SELECT TOP #{limit_amount[0]} * FROM ( SELECT TOP #{limit_amount[1]}")<<" ) AS tmp1 ORDER BY #{order_by[1]} ) AS tmp2 ORDER BY #{order_by[0]}"
|
265
|
+
else
|
266
|
+
sql.gsub!(/SELECT/i, "SELECT TOP #{limit_amount[0]}")
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
188
271
|
def recreate_database(name)
|
189
272
|
drop_database(name)
|
190
273
|
create_database(name)
|
@@ -198,14 +281,18 @@ EOL
|
|
198
281
|
execute "CREATE DATABASE #{name}"
|
199
282
|
end
|
200
283
|
|
201
|
-
def
|
202
|
-
|
203
|
-
|
204
|
-
if limit_amount.size == 2
|
205
|
-
sql.gsub!(/SELECT/i, "SELECT * FROM ( SELECT TOP #{limit_amount[0]} * FROM ( SELECT TOP #{limit_amount[1]}")<<" ) AS tmp1 ORDER BY #{order_by[1]} ) AS tmp2 ORDER BY #{order_by[0]}"
|
284
|
+
def execute(sql, name = nil)
|
285
|
+
if sql =~ /^INSERT/i
|
286
|
+
insert(sql, name)
|
206
287
|
else
|
207
|
-
sql
|
208
|
-
|
288
|
+
log(sql, name, @connection) do |conn|
|
289
|
+
conn.execute(sql)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def adapter_name()
|
295
|
+
'SqlServer'
|
209
296
|
end
|
210
297
|
|
211
298
|
private
|
@@ -266,6 +353,10 @@ EOL
|
|
266
353
|
return sql =~ /[\(\.\,]\s*#{col}/
|
267
354
|
end
|
268
355
|
|
356
|
+
def query_contains_text_column(sql, col)
|
357
|
+
|
358
|
+
end
|
359
|
+
|
269
360
|
def get_order_by(sql)
|
270
361
|
return sql, sql.gsub(/\s*DESC\s*/, "").gsub(/\s*ASC\s*/, " DESC")
|
271
362
|
end
|
@@ -66,7 +66,7 @@ module ActiveRecord
|
|
66
66
|
end_eval
|
67
67
|
end
|
68
68
|
|
69
|
-
def deprecated_association_comparison_method(association_name, association_class_name)
|
69
|
+
def deprecated_association_comparison_method(association_name, association_class_name) # :nodoc:
|
70
70
|
module_eval <<-"end_eval", __FILE__, __LINE__
|
71
71
|
def #{association_name}?(comparison_object, force_reload = false)
|
72
72
|
if comparison_object.kind_of?(#{association_class_name})
|
@@ -78,7 +78,7 @@ module ActiveRecord
|
|
78
78
|
end_eval
|
79
79
|
end
|
80
80
|
|
81
|
-
def deprecated_has_association_method(association_name)
|
81
|
+
def deprecated_has_association_method(association_name) # :nodoc:
|
82
82
|
module_eval <<-"end_eval", __FILE__, __LINE__
|
83
83
|
def has_#{association_name}?(force_reload = false)
|
84
84
|
!#{association_name}(force_reload).nil?
|
@@ -86,7 +86,7 @@ module ActiveRecord
|
|
86
86
|
end_eval
|
87
87
|
end
|
88
88
|
|
89
|
-
def deprecated_build_method(method_prefix, collection_name, collection_class_name, class_primary_key_name)
|
89
|
+
def deprecated_build_method(method_prefix, collection_name, collection_class_name, class_primary_key_name)# :nodoc:
|
90
90
|
module_eval <<-"end_eval", __FILE__, __LINE__
|
91
91
|
def #{method_prefix + collection_name}(attributes = {})
|
92
92
|
association = #{collection_class_name}.new
|
@@ -96,7 +96,7 @@ module ActiveRecord
|
|
96
96
|
end_eval
|
97
97
|
end
|
98
98
|
|
99
|
-
def deprecated_create_method(method_prefix, collection_name, collection_class_name, class_primary_key_name)
|
99
|
+
def deprecated_create_method(method_prefix, collection_name, collection_class_name, class_primary_key_name)# :nodoc:
|
100
100
|
module_eval <<-"end_eval", __FILE__, __LINE__
|
101
101
|
def #{method_prefix + collection_name}(attributes = nil)
|
102
102
|
#{collection_class_name}.create((attributes || {}).merge({ "#{class_primary_key_name}" => id}))
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'yaml'
|
3
3
|
require 'csv'
|
4
|
-
require '
|
5
|
-
require '
|
4
|
+
require 'active_support/class_inheritable_attributes'
|
5
|
+
require 'active_support/inflector'
|
6
6
|
|
7
7
|
# Fixtures are a way of organizing data that you want to test against; in short, sample data. They come in 3 flavours:
|
8
8
|
#
|
@@ -39,7 +39,7 @@ require 'active_record/support/inflector'
|
|
39
39
|
# Fixtures can also be kept in the Comma Separated Value format. Akin to YAML fixtures, CSV fixtures are stored
|
40
40
|
# in a single file, but, instead end with the .csv file extension (Rails example: "<your-rails-app>/test/fixtures/web_sites.csv")
|
41
41
|
#
|
42
|
-
# The format of this
|
42
|
+
# The format of this type of fixture file is much more compact than the others, but also a little harder to read by us
|
43
43
|
# humans. The first line of the CSV file is a comma-separated list of field names. The rest of the file is then comprised
|
44
44
|
# of the actual data (1 per line). Here's an example:
|
45
45
|
#
|
@@ -146,7 +146,11 @@ class Fixtures < Hash
|
|
146
146
|
def self.instantiate_fixtures(object, fixtures_directory, *table_names)
|
147
147
|
[ create_fixtures(fixtures_directory, *table_names) ].flatten.each_with_index do |fixtures, idx|
|
148
148
|
object.instance_variable_set "@#{table_names[idx]}", fixtures
|
149
|
-
fixtures.each
|
149
|
+
fixtures.each do |name, fixture|
|
150
|
+
if model = fixture.find
|
151
|
+
object.instance_variable_set "@#{name}", model
|
152
|
+
end
|
153
|
+
end
|
150
154
|
end
|
151
155
|
end
|
152
156
|
|
@@ -294,7 +298,10 @@ class Fixture #:nodoc:
|
|
294
298
|
end
|
295
299
|
|
296
300
|
def find
|
297
|
-
Object.
|
301
|
+
if Object.const_defined?(@class_name)
|
302
|
+
klass = Object.const_get(@class_name)
|
303
|
+
klass.find(self[klass.primary_key])
|
304
|
+
end
|
298
305
|
end
|
299
306
|
|
300
307
|
private
|