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.

Files changed (96) hide show
  1. data/CHANGELOG +78 -0
  2. data/README +20 -29
  3. data/RUNNING_UNIT_TESTS +1 -2
  4. data/examples/validation.rb +0 -3
  5. data/install.rb +3 -16
  6. data/lib/active_record.rb +11 -4
  7. data/lib/active_record/aggregations.rb +2 -2
  8. data/lib/active_record/associations.rb +8 -8
  9. data/lib/active_record/associations/association_collection.rb +1 -1
  10. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -1
  11. data/lib/active_record/base.rb +117 -43
  12. data/lib/active_record/callbacks.rb +2 -2
  13. data/lib/active_record/connection_adapters/abstract_adapter.rb +7 -14
  14. data/lib/active_record/connection_adapters/db2_adapter.rb +33 -22
  15. data/lib/active_record/connection_adapters/mysql_adapter.rb +74 -33
  16. data/lib/active_record/connection_adapters/oci_adapter.rb +265 -0
  17. data/lib/active_record/connection_adapters/postgresql_adapter.rb +23 -3
  18. data/lib/active_record/connection_adapters/sqlite_adapter.rb +13 -4
  19. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +158 -67
  20. data/lib/active_record/deprecated_associations.rb +4 -4
  21. data/lib/active_record/fixtures.rb +12 -5
  22. data/lib/active_record/locking.rb +22 -22
  23. data/lib/active_record/observer.rb +6 -3
  24. data/lib/active_record/timestamp.rb +15 -5
  25. data/lib/active_record/transactions.rb +4 -4
  26. data/lib/active_record/validations.rb +272 -189
  27. data/lib/active_record/wrappings.rb +2 -2
  28. data/rakefile +17 -2
  29. data/test/aaa_create_tables_test.rb +58 -0
  30. data/test/abstract_unit.rb +3 -2
  31. data/test/aggregations_test.rb +0 -1
  32. data/test/associations_test.rb +27 -28
  33. data/test/base_test.rb +74 -2
  34. data/test/binary_test.rb +6 -2
  35. data/test/class_inheritable_attributes_test.rb +1 -1
  36. data/test/column_alias_test.rb +9 -2
  37. data/test/connections/native_oci/connection.rb +25 -0
  38. data/test/connections/native_sqlite/connection.rb +4 -1
  39. data/test/connections/native_sqlite3/connection.rb +4 -2
  40. data/test/deprecated_associations_test.rb +4 -5
  41. data/test/finder_test.rb +20 -4
  42. data/test/fixtures/db_definitions/create_oracle_db.bat +5 -0
  43. data/test/fixtures/db_definitions/create_oracle_db.sh +5 -0
  44. data/test/fixtures/db_definitions/db2.drop.sql +18 -0
  45. data/test/fixtures/db_definitions/db2.sql +1 -0
  46. data/test/fixtures/db_definitions/db22.drop.sql +2 -0
  47. data/test/fixtures/db_definitions/db22.sql +1 -0
  48. data/test/fixtures/db_definitions/drop_oracle_tables.sql +35 -0
  49. data/test/fixtures/db_definitions/drop_oracle_tables2.sql +3 -0
  50. data/test/fixtures/db_definitions/mysql.drop.sql +18 -0
  51. data/test/fixtures/db_definitions/mysql.sql +2 -1
  52. data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
  53. data/test/fixtures/db_definitions/mysql2.sql +1 -0
  54. data/test/fixtures/db_definitions/oci.drop.sql +18 -0
  55. data/test/fixtures/db_definitions/oci.sql +167 -0
  56. data/test/fixtures/db_definitions/oci2.drop.sql +2 -0
  57. data/test/fixtures/db_definitions/oci2.sql +6 -0
  58. data/test/fixtures/db_definitions/postgresql.drop.sql +18 -0
  59. data/test/fixtures/db_definitions/postgresql.sql +2 -1
  60. data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
  61. data/test/fixtures/db_definitions/postgresql2.sql +2 -1
  62. data/test/fixtures/db_definitions/sqlite.drop.sql +18 -0
  63. data/test/fixtures/db_definitions/sqlite.sql +2 -1
  64. data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
  65. data/test/fixtures/db_definitions/sqlite2.sql +1 -0
  66. data/test/fixtures/db_definitions/sqlserver.drop.sql +18 -0
  67. data/test/fixtures/db_definitions/sqlserver.sql +1 -0
  68. data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
  69. data/test/fixtures/db_definitions/sqlserver2.sql +1 -0
  70. data/test/fixtures/fixture_database.sqlite +0 -0
  71. data/test/fixtures/fixture_database_2.sqlite +0 -0
  72. data/test/fixtures/topics.yml +3 -3
  73. data/test/lifecycle_test.rb +0 -1
  74. data/test/modules_test.rb +0 -1
  75. data/test/reflection_test.rb +0 -1
  76. data/test/validations_test.rb +229 -41
  77. metadata +36 -28
  78. data/dev-utils/eval_debugger.rb +0 -14
  79. data/lib/active_record/support/binding_of_caller.rb +0 -83
  80. data/lib/active_record/support/breakpoint.rb +0 -518
  81. data/lib/active_record/support/class_attribute_accessors.rb +0 -57
  82. data/lib/active_record/support/class_inheritable_attributes.rb +0 -117
  83. data/lib/active_record/support/clean_logger.rb +0 -10
  84. data/lib/active_record/support/core_ext.rb +0 -1
  85. data/lib/active_record/support/core_ext/hash.rb +0 -5
  86. data/lib/active_record/support/core_ext/hash/keys.rb +0 -35
  87. data/lib/active_record/support/core_ext/numeric.rb +0 -7
  88. data/lib/active_record/support/core_ext/numeric/bytes.rb +0 -33
  89. data/lib/active_record/support/core_ext/numeric/time.rb +0 -59
  90. data/lib/active_record/support/core_ext/object_and_class.rb +0 -24
  91. data/lib/active_record/support/core_ext/string.rb +0 -5
  92. data/lib/active_record/support/core_ext/string/inflections.rb +0 -45
  93. data/lib/active_record/support/dependencies.rb +0 -63
  94. data/lib/active_record/support/inflector.rb +0 -84
  95. data/lib/active_record/support/misc.rb +0 -8
  96. 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
- class PostgreSQLAdapter < AbstractAdapter # :nodoc:
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
- class SQLiteAdapter < AbstractAdapter # :nodoc:
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
- class SQLServerAdapter < AbstractAdapter # :nodoc:
65
- def quote_column_name(name)
66
- "[#{name}]"
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 s.name AS TableName, c.id AS ColId, c.name AS ColName, t.name AS ColType, c.length AS Length,
81
- c.AutoVal AS IsIdentity,
82
- c.cdefault AS DefaultId, com.text AS DefaultValue
83
- FROM syscolumns AS c
84
- JOIN systypes AS t ON (c.xtype = t.xtype AND c.usertype = t.usertype)
85
- JOIN sysobjects AS s ON (c.id = s.id)
86
- LEFT OUTER JOIN syscomments AS com ON (c.cdefault = com.id)
87
- WHERE s.name = '#{table_name}'
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
- if default_value =~ /null/i
96
- default_value = nil
97
- else
98
- default_value =~ /\(([^)]+)\)/
99
- default_value = $1
100
- end
101
-
102
- col = ColumnWithIdentity.new(row[:ColName], default_value, "#{row[:ColType]}(#{row[:Length]})", row[:IsIdentity] != nil)
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 add_limit!(sql, limit)
202
- limit_amount = limit.to_s.include?("OFFSET") ? get_offset_amount(limit) : Array.new([limit])
203
- order_by = sql.include?("ORDER BY") ? get_order_by(sql.sub(/.*ORDER\sBY./, "")) : nil
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.gsub!(/SELECT/i, "SELECT TOP #{limit_amount[0]}")
208
- end
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 'active_record/support/class_inheritable_attributes'
5
- require 'active_record/support/inflector'
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 tye of fixture file is much more compact than the others, but also a little harder to read by us
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 { |name, fixture| object.instance_variable_set "@#{name}", fixture.find }
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.const_get(@class_name).find(self[Object.const_get(@class_name).primary_key])
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