activerecord 3.2.2 → 3.2.3.rc1

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 (28) hide show
  1. data/CHANGELOG.md +27 -2
  2. data/lib/active_record/aggregations.rb +1 -1
  3. data/lib/active_record/associations.rb +2 -2
  4. data/lib/active_record/associations/alias_tracker.rb +3 -6
  5. data/lib/active_record/associations/association.rb +2 -1
  6. data/lib/active_record/associations/association_scope.rb +1 -1
  7. data/lib/active_record/associations/has_many_through_association.rb +3 -1
  8. data/lib/active_record/associations/join_dependency.rb +1 -1
  9. data/lib/active_record/associations/through_association.rb +7 -3
  10. data/lib/active_record/attribute_methods.rb +1 -1
  11. data/lib/active_record/base.rb +4 -1
  12. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +39 -15
  13. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +4 -4
  14. data/lib/active_record/connection_adapters/abstract_adapter.rb +1 -1
  15. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +20 -9
  16. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -1
  17. data/lib/active_record/connection_adapters/sqlite_adapter.rb +1 -1
  18. data/lib/active_record/dynamic_finder_match.rb +12 -0
  19. data/lib/active_record/migration.rb +22 -6
  20. data/lib/active_record/railties/databases.rake +1 -0
  21. data/lib/active_record/relation/finder_methods.rb +1 -1
  22. data/lib/active_record/relation/query_methods.rb +1 -1
  23. data/lib/active_record/schema_dumper.rb +1 -1
  24. data/lib/active_record/version.rb +2 -2
  25. data/lib/rails/generators/active_record/migration/templates/migration.rb +4 -1
  26. data/lib/rails/generators/active_record/model/model_generator.rb +4 -0
  27. data/lib/rails/generators/active_record/model/templates/model.rb +5 -0
  28. metadata +42 -32
@@ -1,3 +1,25 @@
1
+ ## Rails 3.2.3 (unreleased) ##
2
+
3
+ * Added find_or_create_by_{attribute}! dynamic method. *Andrew White*
4
+
5
+ * Whitelist all attribute assignment by default. Change the default for newly generated applications to whitelist all attribute assignment. Also update the generated model classes so users are reminded of the importance of attr_accessible. *NZKoz*
6
+
7
+ * Update ActiveRecord::AttributeMethods#attribute_present? to return false for empty strings. *Jacobkg*
8
+
9
+ * Fix associations when using per class databases. *larskanis*
10
+
11
+ * Revert setting NOT NULL constraints in add_timestamps *fxn*
12
+
13
+ * Fix mysql to use proper text types. Fixes #3931. *kennyj*
14
+
15
+ * Fix #5069 - Protect foreign key from mass assignment through association builder. *byroot*
16
+
17
+
18
+ ## Rails 3.2.2 (March 1, 2012) ##
19
+
20
+ * No changes.
21
+
22
+
1
23
  ## Rails 3.2.1 (January 26, 2012) ##
2
24
 
3
25
  * The threshold for auto EXPLAIN is ignored if there's no logger. *fxn*
@@ -192,7 +214,8 @@
192
214
 
193
215
  *Brian Durand*
194
216
 
195
- ## Rails 3.1.3 (unreleased) ##
217
+
218
+ ## Rails 3.1.3 (November 20, 2011) ##
196
219
 
197
220
  * Perf fix: If we're deleting all records in an association, don't add a IN(..) clause
198
221
  to the query. *GH 3672*
@@ -205,7 +228,8 @@
205
228
 
206
229
  *Christos Zisopoulos and Kenny J*
207
230
 
208
- ## Rails 3.1.2 (unreleased) ##
231
+
232
+ ## Rails 3.1.2 (November 18, 2011) ##
209
233
 
210
234
  * Fix bug with PostgreSQLAdapter#indexes. When the search path has multiple schemas, spaces
211
235
  were not being stripped from the schema names after the first.
@@ -252,6 +276,7 @@
252
276
 
253
277
  *Kenny J*
254
278
 
279
+
255
280
  ## Rails 3.1.1 (October 7, 2011) ##
256
281
 
257
282
  * Add deprecation for the preload_associations method. Fixes #3022.
@@ -46,7 +46,7 @@ module ActiveRecord
46
46
  #
47
47
  # def <=>(other_money)
48
48
  # if currency == other_money.currency
49
- # amount <=> amount
49
+ # amount <=> other_money.amount
50
50
  # else
51
51
  # amount <=> other_money.exchange_to(currency).amount
52
52
  # end
@@ -1513,8 +1513,8 @@ module ActiveRecord
1513
1513
  # * <tt>Developer#projects.size</tt>
1514
1514
  # * <tt>Developer#projects.find(id)</tt>
1515
1515
  # * <tt>Developer#projects.exists?(...)</tt>
1516
- # * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("project_id" => id)</tt>)
1517
- # * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("project_id" => id); c.save; c</tt>)
1516
+ # * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("developer_id" => id)</tt>)
1517
+ # * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("developer_id" => id); c.save; c</tt>)
1518
1518
  # The declaration may include an options hash to specialize the behavior of the association.
1519
1519
  #
1520
1520
  # === Options
@@ -5,12 +5,13 @@ module ActiveRecord
5
5
  # Keeps track of table aliases for ActiveRecord::Associations::ClassMethods::JoinDependency and
6
6
  # ActiveRecord::Associations::ThroughAssociationScope
7
7
  class AliasTracker # :nodoc:
8
- attr_reader :aliases, :table_joins
8
+ attr_reader :aliases, :table_joins, :connection
9
9
 
10
10
  # table_joins is an array of arel joins which might conflict with the aliases we assign here
11
- def initialize(table_joins = [])
11
+ def initialize(connection = ActiveRecord::Model.connection, table_joins = [])
12
12
  @aliases = Hash.new { |h,k| h[k] = initial_count_for(k) }
13
13
  @table_joins = table_joins
14
+ @connection = connection
14
15
  end
15
16
 
16
17
  def aliased_table_for(table_name, aliased_name = nil)
@@ -70,10 +71,6 @@ module ActiveRecord
70
71
  def truncate(name)
71
72
  name.slice(0, connection.table_alias_length - 2)
72
73
  end
73
-
74
- def connection
75
- ActiveRecord::Base.connection
76
- end
77
74
  end
78
75
  end
79
76
  end
@@ -231,7 +231,8 @@ module ActiveRecord
231
231
 
232
232
  def build_record(attributes, options)
233
233
  reflection.build_association(attributes, options) do |record|
234
- record.assign_attributes(create_scope.except(*record.changed), :without_protection => true)
234
+ attributes = create_scope.except(*(record.changed - [reflection.foreign_key]))
235
+ record.assign_attributes(attributes, :without_protection => true)
235
236
  end
236
237
  end
237
238
  end
@@ -10,7 +10,7 @@ module ActiveRecord
10
10
 
11
11
  def initialize(association)
12
12
  @association = association
13
- @alias_tracker = AliasTracker.new
13
+ @alias_tracker = AliasTracker.new klass.connection
14
14
  end
15
15
 
16
16
  def scope
@@ -73,7 +73,9 @@ module ActiveRecord
73
73
  # association
74
74
  def build_through_record(record)
75
75
  @through_records[record.object_id] ||= begin
76
- through_record = through_association.build(construct_join_attributes(record))
76
+ ensure_mutable
77
+
78
+ through_record = through_association.build
77
79
  through_record.send("#{source_reflection.name}=", record)
78
80
  through_record
79
81
  end
@@ -13,7 +13,7 @@ module ActiveRecord
13
13
  @join_parts = [JoinBase.new(base)]
14
14
  @associations = {}
15
15
  @reflections = []
16
- @alias_tracker = AliasTracker.new(joins)
16
+ @alias_tracker = AliasTracker.new(base.connection, joins)
17
17
  @alias_tracker.aliased_name_for(base.table_name) # Updates the count for base.table_name to 1
18
18
  build(associations)
19
19
  end
@@ -37,9 +37,7 @@ module ActiveRecord
37
37
  # situation it is more natural for the user to just create or modify their join records
38
38
  # directly as required.
39
39
  def construct_join_attributes(*records)
40
- if source_reflection.macro != :belongs_to
41
- raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
42
- end
40
+ ensure_mutable
43
41
 
44
42
  join_attributes = {
45
43
  source_reflection.foreign_key =>
@@ -73,6 +71,12 @@ module ActiveRecord
73
71
  !owner[through_reflection.foreign_key].nil?
74
72
  end
75
73
 
74
+ def ensure_mutable
75
+ if source_reflection.macro != :belongs_to
76
+ raise HasManyThroughCantAssociateThroughHasOneOrManyReflection.new(owner, reflection)
77
+ end
78
+ end
79
+
76
80
  def ensure_not_nested
77
81
  if reflection.nested?
78
82
  raise HasManyThroughNestedAssociationsAreReadonly.new(owner, reflection)
@@ -212,7 +212,7 @@ module ActiveRecord
212
212
  # nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings).
213
213
  def attribute_present?(attribute)
214
214
  value = read_attribute(attribute)
215
- !value.nil? || (value.respond_to?(:empty?) && !value.empty?)
215
+ !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
216
216
  end
217
217
 
218
218
  # Returns the column object for the named attribute.
@@ -208,6 +208,9 @@ module ActiveRecord #:nodoc:
208
208
  # # Now 'Bob' exist and is an 'admin'
209
209
  # User.find_or_create_by_name('Bob', :age => 40) { |u| u.admin = true }
210
210
  #
211
+ # Adding an exclamation point (!) on to the end of <tt>find_or_create_by_</tt> will
212
+ # raise an <tt>ActiveRecord::RecordInvalid</tt> error if the new record is invalid.
213
+ #
211
214
  # Use the <tt>find_or_initialize_by_</tt> finder if you want to return a new record without
212
215
  # saving it first. Protected attributes won't be set unless they are given in a block.
213
216
  #
@@ -439,7 +442,7 @@ module ActiveRecord #:nodoc:
439
442
  if self == ActiveRecord::Base
440
443
  ActiveRecord::Base
441
444
  else
442
- connection_handler.connection_pools[name] ? self : superclass.arel_engine
445
+ connection_handler.retrieve_connection_pool(self) ? self : superclass.arel_engine
443
446
  end
444
447
  end
445
448
  end
@@ -95,10 +95,11 @@ module ActiveRecord
95
95
  @reserved_connections[current_connection_id] ||= checkout
96
96
  end
97
97
 
98
- # Check to see if there is an active connection in this connection
99
- # pool.
98
+ # Is there an open connection that is being used for the current thread?
100
99
  def active_connection?
101
- active_connections.any?
100
+ @reserved_connections.fetch(current_connection_id) {
101
+ return false
102
+ }.in_use?
102
103
  end
103
104
 
104
105
  # Signal that the thread is finished with the current connection.
@@ -225,8 +226,9 @@ connection. For example: ActiveRecord::Base.connection.close
225
226
  # - ConnectionTimeoutError: no connection can be obtained from the pool
226
227
  # within the timeout period.
227
228
  def checkout
228
- # Checkout an available connection
229
229
  synchronize do
230
+ waited_time = 0
231
+
230
232
  loop do
231
233
  conn = @connections.find { |c| c.lease }
232
234
 
@@ -242,17 +244,25 @@ connection. For example: ActiveRecord::Base.connection.close
242
244
  return conn
243
245
  end
244
246
 
245
- @queue.wait(@timeout)
247
+ if waited_time >= @timeout
248
+ raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout} (waited #{waited_time} seconds). The max pool size is currently #{@size}; consider increasing it."
249
+ end
246
250
 
247
- if(active_connections.size < @connections.size)
248
- next
249
- else
251
+ # Sometimes our wait can end because a connection is available,
252
+ # but another thread can snatch it up first. If timeout hasn't
253
+ # passed but no connection is avail, looks like that happened --
254
+ # loop and wait again, for the time remaining on our timeout.
255
+ before_wait = Time.now
256
+ @queue.wait( [@timeout - waited_time, 0].max )
257
+ waited_time += (Time.now - before_wait)
258
+
259
+ # Will go away in Rails 4, when we don't clean up
260
+ # after leaked connections automatically anymore. Right now, clean
261
+ # up after we've returned from a 'wait' if it looks like it's
262
+ # needed, then loop and try again.
263
+ if(active_connections.size >= @connections.size)
250
264
  clear_stale_cached_connections!
251
- if @size == active_connections.size
252
- raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout}. The max pool size is currently #{@size}; consider increasing it."
253
- end
254
265
  end
255
-
256
266
  end
257
267
  end
258
268
  end
@@ -268,11 +278,27 @@ connection. For example: ActiveRecord::Base.connection.close
268
278
  conn.expire
269
279
  @queue.signal
270
280
  end
281
+
282
+ release conn
271
283
  end
272
284
  end
273
285
 
274
286
  private
275
287
 
288
+ def release(conn)
289
+ thread_id = nil
290
+
291
+ if @reserved_connections[current_connection_id] == conn
292
+ thread_id = current_connection_id
293
+ else
294
+ thread_id = @reserved_connections.keys.find { |k|
295
+ @reserved_connections[k] == conn
296
+ }
297
+ end
298
+
299
+ @reserved_connections.delete thread_id if thread_id
300
+ end
301
+
276
302
  def new_connection
277
303
  ActiveRecord::Base.send(spec.adapter_method, spec.config)
278
304
  end
@@ -344,9 +370,7 @@ connection. For example: ActiveRecord::Base.connection.close
344
370
  connection_pools.values.any? { |pool| pool.active_connection? }
345
371
  end
346
372
 
347
- # Returns any connections in use by the current thread back to the pool,
348
- # and also returns connections to the pool cached by threads that are no
349
- # longer alive.
373
+ # Returns any connections in use by the current thread back to the pool.
350
374
  def clear_active_connections!
351
375
  @connection_pools.each_value {|pool| pool.release_connection }
352
376
  end
@@ -160,7 +160,7 @@ module ActiveRecord
160
160
  yield td if block_given?
161
161
 
162
162
  if options[:force] && table_exists?(table_name)
163
- drop_table(table_name)
163
+ drop_table(table_name, options)
164
164
  end
165
165
 
166
166
  create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
@@ -252,7 +252,7 @@ module ActiveRecord
252
252
  end
253
253
 
254
254
  # Drops a table from the database.
255
- def drop_table(table_name)
255
+ def drop_table(table_name, options = {})
256
256
  execute "DROP TABLE #{quote_table_name(table_name)}"
257
257
  end
258
258
 
@@ -508,8 +508,8 @@ module ActiveRecord
508
508
  # ===== Examples
509
509
  # add_timestamps(:suppliers)
510
510
  def add_timestamps(table_name)
511
- add_column table_name, :created_at, :datetime, :null => false
512
- add_column table_name, :updated_at, :datetime, :null => false
511
+ add_column table_name, :created_at, :datetime
512
+ add_column table_name, :updated_at, :datetime
513
513
  end
514
514
 
515
515
  # Removes the timestamp columns (created_at and updated_at) from the table definition.
@@ -54,7 +54,7 @@ module ActiveRecord
54
54
  define_callbacks :checkout, :checkin
55
55
 
56
56
  attr_accessor :visitor, :pool
57
- attr_reader :schema_cache, :last_use, :in_use
57
+ attr_reader :schema_cache, :last_use, :in_use, :logger
58
58
  alias :in_use? :in_use
59
59
 
60
60
  def initialize(connection, logger = nil, pool = nil) #:nodoc:
@@ -484,15 +484,26 @@ module ActiveRecord
484
484
 
485
485
  # Maps logical Rails types to MySQL-specific data types.
486
486
  def type_to_sql(type, limit = nil, precision = nil, scale = nil)
487
- return super unless type.to_s == 'integer'
488
-
489
- case limit
490
- when 1; 'tinyint'
491
- when 2; 'smallint'
492
- when 3; 'mediumint'
493
- when nil, 4, 11; 'int(11)' # compatibility with MySQL default
494
- when 5..8; 'bigint'
495
- else raise(ActiveRecordError, "No integer type has byte size #{limit}")
487
+ case type.to_s
488
+ when 'integer'
489
+ case limit
490
+ when 1; 'tinyint'
491
+ when 2; 'smallint'
492
+ when 3; 'mediumint'
493
+ when nil, 4, 11; 'int(11)' # compatibility with MySQL default
494
+ when 5..8; 'bigint'
495
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}")
496
+ end
497
+ when 'text'
498
+ case limit
499
+ when 0..0xff; 'tinytext'
500
+ when nil, 0x100..0xffff; 'text'
501
+ when 0x10000..0xffffff; 'mediumtext'
502
+ when 0x1000000..0xffffffff; 'longtext'
503
+ else raise(ActiveRecordError, "No text type has character length #{limit}")
504
+ end
505
+ else
506
+ super
496
507
  end
497
508
  end
498
509
 
@@ -885,7 +885,7 @@ module ActiveRecord
885
885
  # This should be not be called manually but set in database.yml.
886
886
  def schema_search_path=(schema_csv)
887
887
  if schema_csv
888
- execute "SET search_path TO #{schema_csv}"
888
+ execute("SET search_path TO #{schema_csv}", 'SCHEMA')
889
889
  @schema_search_path = schema_csv
890
890
  end
891
891
  end
@@ -204,7 +204,7 @@ module ActiveRecord
204
204
 
205
205
  value = super
206
206
  if column.type == :string && value.encoding == Encoding::ASCII_8BIT
207
- @logger.error "Binary data inserted for `string` type on column `#{column.name}`"
207
+ logger.error "Binary data inserted for `string` type on column `#{column.name}`" if logger
208
208
  value.encode! 'utf-8'
209
209
  end
210
210
  value
@@ -18,6 +18,10 @@ module ActiveRecord
18
18
  when /^find_by_([_a-zA-Z]\w*)\!$/
19
19
  bang = true
20
20
  names = $1
21
+ when /^find_or_create_by_([_a-zA-Z]\w*)\!$/
22
+ bang = true
23
+ instantiator = :create
24
+ names = $1
21
25
  when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
22
26
  instantiator = $1 == 'initialize' ? :new : :create
23
27
  names = $2
@@ -52,5 +56,13 @@ module ActiveRecord
52
56
  def bang?
53
57
  @bang
54
58
  end
59
+
60
+ def save_record?
61
+ @instantiator == :create
62
+ end
63
+
64
+ def save_method
65
+ bang? ? :save! : :save
66
+ end
55
67
  end
56
68
  end
@@ -346,12 +346,24 @@ module ActiveRecord
346
346
  @name = self.class.name
347
347
  @version = nil
348
348
  @connection = nil
349
+ @reverting = false
349
350
  end
350
351
 
351
352
  # instantiate the delegate object after initialize is defined
352
353
  self.verbose = true
353
354
  self.delegate = new
354
355
 
356
+ def revert
357
+ @reverting = true
358
+ yield
359
+ ensure
360
+ @reverting = false
361
+ end
362
+
363
+ def reverting?
364
+ @reverting
365
+ end
366
+
355
367
  def up
356
368
  self.class.delegate = self
357
369
  return unless self.class.respond_to?(:up)
@@ -385,9 +397,11 @@ module ActiveRecord
385
397
  end
386
398
  @connection = conn
387
399
  time = Benchmark.measure {
388
- recorder.inverse.each do |cmd, args|
389
- send(cmd, *args)
390
- end
400
+ self.revert {
401
+ recorder.inverse.each do |cmd, args|
402
+ send(cmd, *args)
403
+ end
404
+ }
391
405
  }
392
406
  else
393
407
  time = Benchmark.measure { change }
@@ -442,9 +456,11 @@ module ActiveRecord
442
456
  arg_list = arguments.map{ |a| a.inspect } * ', '
443
457
 
444
458
  say_with_time "#{method}(#{arg_list})" do
445
- unless arguments.empty? || method == :execute
446
- arguments[0] = Migrator.proper_table_name(arguments.first)
447
- arguments[1] = Migrator.proper_table_name(arguments.second) if method == :rename_table
459
+ unless reverting?
460
+ unless arguments.empty? || method == :execute
461
+ arguments[0] = Migrator.proper_table_name(arguments.first)
462
+ arguments[1] = Migrator.proper_table_name(arguments.second) if method == :rename_table
463
+ end
448
464
  end
449
465
  return super unless connection.respond_to?(method)
450
466
  connection.send(method, *arguments, &block)
@@ -407,6 +407,7 @@ db_namespace = namespace :db do
407
407
  if ActiveRecord::Base.connection.supports_migrations?
408
408
  File.open(filename, "a") { |f| f << ActiveRecord::Base.connection.dump_schema_information }
409
409
  end
410
+ db_namespace['structure:dump'].reenable
410
411
  end
411
412
 
412
413
  # desc "Recreate the databases from the structure.sql file"
@@ -290,7 +290,7 @@ module ActiveRecord
290
290
  r.assign_attributes(unprotected_attributes_for_create, :without_protection => true)
291
291
  end
292
292
  yield(record) if block_given?
293
- record.save if match.instantiator == :create
293
+ record.send(match.save_method) if match.save_record?
294
294
  end
295
295
 
296
296
  record
@@ -270,7 +270,7 @@ module ActiveRecord
270
270
  arel.having(*@having_values.uniq.reject{|h| h.blank?}) unless @having_values.empty?
271
271
 
272
272
  arel.take(connection.sanitize_limit(@limit_value)) if @limit_value
273
- arel.skip(@offset_value) if @offset_value
273
+ arel.skip(@offset_value.to_i) if @offset_value
274
274
 
275
275
  arel.group(*@group_values.uniq.reject{|g| g.blank?}) unless @group_values.empty?
276
276
 
@@ -40,7 +40,7 @@ module ActiveRecord
40
40
  def header(stream)
41
41
  define_params = @version ? ":version => #{@version}" : ""
42
42
 
43
- if stream.respond_to?(:external_encoding)
43
+ if stream.respond_to?(:external_encoding) && stream.external_encoding
44
44
  stream.puts "# encoding: #{stream.external_encoding.name}"
45
45
  end
46
46
 
@@ -2,8 +2,8 @@ module ActiveRecord
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
4
  MINOR = 2
5
- TINY = 2
6
- PRE = nil
5
+ TINY = 3
6
+ PRE = "rc1"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
  end
@@ -5,7 +5,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration
5
5
  add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
6
6
  <%- if attribute.has_index? -%>
7
7
  add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
8
- <%- end %>
8
+ <%- end -%>
9
9
  <%- end -%>
10
10
  end
11
11
  <%- else -%>
@@ -24,6 +24,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration
24
24
  <% attributes.reverse.each do |attribute| -%>
25
25
  <%- if migration_action -%>
26
26
  <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
27
+ <%- if attribute.has_index? && migration_action == 'remove' -%>
28
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
29
+ <%- end -%>
27
30
  <%- end -%>
28
31
  <%- end -%>
29
32
  end
@@ -30,6 +30,10 @@ module ActiveRecord
30
30
  attributes.select { |a| a.has_index? || (a.reference? && options[:indexes]) }
31
31
  end
32
32
 
33
+ def accessible_attributes
34
+ attributes.reject(&:reference?)
35
+ end
36
+
33
37
  hook_for :test_framework
34
38
 
35
39
  protected
@@ -3,5 +3,10 @@ class <%= class_name %> < <%= parent_class_name.classify %>
3
3
  <% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
4
4
  belongs_to :<%= attribute.name %>
5
5
  <% end -%>
6
+ <% if !accessible_attributes.empty? -%>
7
+ attr_accessible <%= accessible_attributes.map {|a| ":#{a.name}" }.sort.join(', ') %>
8
+ <% else -%>
9
+ # attr_accessible :title, :body
10
+ <% end -%>
6
11
  end
7
12
  <% end -%>
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
5
- prerelease:
4
+ hash: 15424079
5
+ prerelease: true
6
6
  segments:
7
7
  - 3
8
8
  - 2
9
- - 2
10
- version: 3.2.2
9
+ - 3
10
+ - rc
11
+ - 1
12
+ version: 3.2.3.rc1
11
13
  platform: ruby
12
14
  authors:
13
15
  - David Heinemeier Hansson
@@ -15,44 +17,47 @@ autorequire:
15
17
  bindir: bin
16
18
  cert_chain: []
17
19
 
18
- date: 2012-03-01 00:00:00 Z
20
+ date: 2012-03-27 00:00:00 -03:00
21
+ default_executable:
19
22
  dependencies:
20
23
  - !ruby/object:Gem::Dependency
21
- name: activesupport
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
24
25
  none: false
25
26
  requirements:
26
27
  - - "="
27
28
  - !ruby/object:Gem::Version
28
- hash: 11
29
+ hash: 15424079
29
30
  segments:
30
31
  - 3
31
32
  - 2
32
- - 2
33
- version: 3.2.2
33
+ - 3
34
+ - rc
35
+ - 1
36
+ version: 3.2.3.rc1
37
+ requirement: *id001
34
38
  type: :runtime
35
- version_requirements: *id001
36
- - !ruby/object:Gem::Dependency
37
- name: activemodel
39
+ name: activesupport
38
40
  prerelease: false
39
- requirement: &id002 !ruby/object:Gem::Requirement
41
+ - !ruby/object:Gem::Dependency
42
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
43
  none: false
41
44
  requirements:
42
45
  - - "="
43
46
  - !ruby/object:Gem::Version
44
- hash: 11
47
+ hash: 15424079
45
48
  segments:
46
49
  - 3
47
50
  - 2
48
- - 2
49
- version: 3.2.2
51
+ - 3
52
+ - rc
53
+ - 1
54
+ version: 3.2.3.rc1
55
+ requirement: *id002
50
56
  type: :runtime
51
- version_requirements: *id002
52
- - !ruby/object:Gem::Dependency
53
- name: arel
57
+ name: activemodel
54
58
  prerelease: false
55
- requirement: &id003 !ruby/object:Gem::Requirement
59
+ - !ruby/object:Gem::Dependency
60
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
61
  none: false
57
62
  requirements:
58
63
  - - ~>
@@ -63,12 +68,12 @@ dependencies:
63
68
  - 0
64
69
  - 2
65
70
  version: 3.0.2
71
+ requirement: *id003
66
72
  type: :runtime
67
- version_requirements: *id003
68
- - !ruby/object:Gem::Dependency
69
- name: tzinfo
73
+ name: arel
70
74
  prerelease: false
71
- requirement: &id004 !ruby/object:Gem::Requirement
75
+ - !ruby/object:Gem::Dependency
76
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
77
  none: false
73
78
  requirements:
74
79
  - - ~>
@@ -79,8 +84,10 @@ dependencies:
79
84
  - 3
80
85
  - 29
81
86
  version: 0.3.29
87
+ requirement: *id004
82
88
  type: :runtime
83
- version_requirements: *id004
89
+ name: tzinfo
90
+ prerelease: false
84
91
  description: Databases on Rails. Build a persistent domain model by mapping database tables to Ruby classes. Strong conventions for associations, validations, aggregations, migrations, and testing come baked-in.
85
92
  email: david@loudthinking.com
86
93
  executables: []
@@ -239,6 +246,7 @@ files:
239
246
  - lib/rails/generators/active_record/session_migration/session_migration_generator.rb
240
247
  - lib/rails/generators/active_record/session_migration/templates/migration.rb
241
248
  - lib/rails/generators/active_record.rb
249
+ has_rdoc: true
242
250
  homepage: http://www.rubyonrails.org
243
251
  licenses: []
244
252
 
@@ -262,16 +270,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
270
  required_rubygems_version: !ruby/object:Gem::Requirement
263
271
  none: false
264
272
  requirements:
265
- - - ">="
273
+ - - ">"
266
274
  - !ruby/object:Gem::Version
267
- hash: 3
275
+ hash: 25
268
276
  segments:
269
- - 0
270
- version: "0"
277
+ - 1
278
+ - 3
279
+ - 1
280
+ version: 1.3.1
271
281
  requirements: []
272
282
 
273
283
  rubyforge_project:
274
- rubygems_version: 1.8.16
284
+ rubygems_version: 1.3.7
275
285
  signing_key:
276
286
  specification_version: 3
277
287
  summary: Object-relational mapper framework (part of Rails).