activerecord 3.1.12 → 3.2.22.1

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 (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +804 -338
  3. data/README.rdoc +3 -3
  4. data/examples/performance.rb +20 -1
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/associations/alias_tracker.rb +3 -6
  7. data/lib/active_record/associations/association.rb +13 -45
  8. data/lib/active_record/associations/association_scope.rb +3 -15
  9. data/lib/active_record/associations/belongs_to_association.rb +1 -1
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +2 -1
  11. data/lib/active_record/associations/builder/association.rb +6 -4
  12. data/lib/active_record/associations/builder/belongs_to.rb +7 -4
  13. data/lib/active_record/associations/builder/collection_association.rb +2 -2
  14. data/lib/active_record/associations/builder/has_many.rb +4 -4
  15. data/lib/active_record/associations/builder/has_one.rb +5 -6
  16. data/lib/active_record/associations/builder/singular_association.rb +3 -16
  17. data/lib/active_record/associations/collection_association.rb +65 -32
  18. data/lib/active_record/associations/collection_proxy.rb +8 -41
  19. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +1 -0
  20. data/lib/active_record/associations/has_many_association.rb +11 -7
  21. data/lib/active_record/associations/has_many_through_association.rb +19 -9
  22. data/lib/active_record/associations/has_one_association.rb +23 -13
  23. data/lib/active_record/associations/join_dependency/join_association.rb +6 -1
  24. data/lib/active_record/associations/join_dependency.rb +3 -3
  25. data/lib/active_record/associations/preloader/through_association.rb +3 -3
  26. data/lib/active_record/associations/preloader.rb +14 -10
  27. data/lib/active_record/associations/through_association.rb +8 -4
  28. data/lib/active_record/associations.rb +92 -76
  29. data/lib/active_record/attribute_assignment.rb +221 -0
  30. data/lib/active_record/attribute_methods/deprecated_underscore_read.rb +32 -0
  31. data/lib/active_record/attribute_methods/dirty.rb +21 -11
  32. data/lib/active_record/attribute_methods/primary_key.rb +62 -25
  33. data/lib/active_record/attribute_methods/read.rb +73 -83
  34. data/lib/active_record/attribute_methods/serialization.rb +120 -0
  35. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -14
  36. data/lib/active_record/attribute_methods/write.rb +32 -6
  37. data/lib/active_record/attribute_methods.rb +231 -30
  38. data/lib/active_record/autosave_association.rb +44 -26
  39. data/lib/active_record/base.rb +227 -1708
  40. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +150 -148
  41. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +85 -29
  42. data/lib/active_record/connection_adapters/abstract/database_statements.rb +7 -34
  43. data/lib/active_record/connection_adapters/abstract/query_cache.rb +10 -2
  44. data/lib/active_record/connection_adapters/abstract/quoting.rb +7 -4
  45. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +39 -28
  46. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +48 -19
  47. data/lib/active_record/connection_adapters/abstract_adapter.rb +77 -42
  48. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +676 -0
  49. data/lib/active_record/connection_adapters/column.rb +37 -11
  50. data/lib/active_record/connection_adapters/mysql2_adapter.rb +133 -581
  51. data/lib/active_record/connection_adapters/mysql_adapter.rb +136 -693
  52. data/lib/active_record/connection_adapters/postgresql_adapter.rb +209 -97
  53. data/lib/active_record/connection_adapters/schema_cache.rb +69 -0
  54. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +2 -6
  55. data/lib/active_record/connection_adapters/sqlite_adapter.rb +62 -35
  56. data/lib/active_record/counter_cache.rb +9 -4
  57. data/lib/active_record/dynamic_finder_match.rb +12 -0
  58. data/lib/active_record/dynamic_matchers.rb +84 -0
  59. data/lib/active_record/errors.rb +11 -1
  60. data/lib/active_record/explain.rb +86 -0
  61. data/lib/active_record/explain_subscriber.rb +25 -0
  62. data/lib/active_record/fixtures/file.rb +65 -0
  63. data/lib/active_record/fixtures.rb +57 -86
  64. data/lib/active_record/identity_map.rb +3 -4
  65. data/lib/active_record/inheritance.rb +174 -0
  66. data/lib/active_record/integration.rb +60 -0
  67. data/lib/active_record/locking/optimistic.rb +33 -26
  68. data/lib/active_record/locking/pessimistic.rb +23 -1
  69. data/lib/active_record/log_subscriber.rb +8 -4
  70. data/lib/active_record/migration/command_recorder.rb +8 -8
  71. data/lib/active_record/migration.rb +68 -35
  72. data/lib/active_record/model_schema.rb +368 -0
  73. data/lib/active_record/nested_attributes.rb +60 -24
  74. data/lib/active_record/persistence.rb +57 -11
  75. data/lib/active_record/query_cache.rb +6 -6
  76. data/lib/active_record/querying.rb +58 -0
  77. data/lib/active_record/railtie.rb +37 -29
  78. data/lib/active_record/railties/controller_runtime.rb +3 -1
  79. data/lib/active_record/railties/databases.rake +213 -117
  80. data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
  81. data/lib/active_record/readonly_attributes.rb +26 -0
  82. data/lib/active_record/reflection.rb +7 -15
  83. data/lib/active_record/relation/batches.rb +7 -4
  84. data/lib/active_record/relation/calculations.rb +55 -16
  85. data/lib/active_record/relation/delegation.rb +49 -0
  86. data/lib/active_record/relation/finder_methods.rb +16 -11
  87. data/lib/active_record/relation/predicate_builder.rb +8 -6
  88. data/lib/active_record/relation/query_methods.rb +75 -9
  89. data/lib/active_record/relation/spawn_methods.rb +48 -7
  90. data/lib/active_record/relation.rb +78 -32
  91. data/lib/active_record/result.rb +10 -4
  92. data/lib/active_record/sanitization.rb +194 -0
  93. data/lib/active_record/schema_dumper.rb +12 -5
  94. data/lib/active_record/scoping/default.rb +142 -0
  95. data/lib/active_record/scoping/named.rb +200 -0
  96. data/lib/active_record/scoping.rb +152 -0
  97. data/lib/active_record/serialization.rb +1 -43
  98. data/lib/active_record/serializers/xml_serializer.rb +4 -45
  99. data/lib/active_record/session_store.rb +18 -16
  100. data/lib/active_record/store.rb +52 -0
  101. data/lib/active_record/test_case.rb +11 -7
  102. data/lib/active_record/timestamp.rb +17 -3
  103. data/lib/active_record/transactions.rb +27 -6
  104. data/lib/active_record/translation.rb +22 -0
  105. data/lib/active_record/validations/associated.rb +5 -4
  106. data/lib/active_record/validations/uniqueness.rb +8 -8
  107. data/lib/active_record/validations.rb +1 -1
  108. data/lib/active_record/version.rb +3 -3
  109. data/lib/active_record.rb +38 -3
  110. data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -1
  111. data/lib/rails/generators/active_record/migration/templates/migration.rb +12 -3
  112. data/lib/rails/generators/active_record/model/model_generator.rb +9 -1
  113. data/lib/rails/generators/active_record/model/templates/migration.rb +3 -5
  114. data/lib/rails/generators/active_record/model/templates/model.rb +5 -0
  115. data/lib/rails/generators/active_record/session_migration/templates/migration.rb +1 -5
  116. metadata +49 -28
  117. data/lib/active_record/named_scope.rb +0 -200
@@ -33,10 +33,15 @@ module ActiveRecord
33
33
  extend ActiveSupport::Concern
34
34
 
35
35
  included do
36
- class_attribute :record_timestamps, :instance_writer => false
36
+ class_attribute :record_timestamps
37
37
  self.record_timestamps = true
38
38
  end
39
39
 
40
+ def initialize_dup(other)
41
+ clear_timestamp_attributes
42
+ super
43
+ end
44
+
40
45
  private
41
46
 
42
47
  def create #:nodoc:
@@ -44,7 +49,9 @@ module ActiveRecord
44
49
  current_time = current_time_from_proper_timezone
45
50
 
46
51
  all_timestamp_attributes.each do |column|
47
- write_attribute(column.to_s, current_time) if respond_to?(column) && self.send(column).nil?
52
+ if respond_to?(column) && respond_to?("#{column}=") && self.send(column).nil?
53
+ write_attribute(column.to_s, current_time)
54
+ end
48
55
  end
49
56
  end
50
57
 
@@ -95,6 +102,13 @@ module ActiveRecord
95
102
  def current_time_from_proper_timezone #:nodoc:
96
103
  self.class.default_timezone == :utc ? Time.now.utc : Time.now
97
104
  end
105
+
106
+ # Clear attributes and changed_attributes
107
+ def clear_timestamp_attributes
108
+ all_timestamp_attributes_in_model.each do |attribute_name|
109
+ self[attribute_name] = nil
110
+ changed_attributes.delete(attribute_name)
111
+ end
112
+ end
98
113
  end
99
114
  end
100
-
@@ -208,6 +208,21 @@ module ActiveRecord
208
208
  connection.transaction(options, &block)
209
209
  end
210
210
 
211
+ # This callback is called after a record has been created, updated, or destroyed.
212
+ #
213
+ # You can specify that the callback should only be fired by a certain action with
214
+ # the +:on+ option:
215
+ #
216
+ # after_commit :do_foo, :on => :create
217
+ # after_commit :do_bar, :on => :update
218
+ # after_commit :do_baz, :on => :destroy
219
+ #
220
+ # Also, to have the callback fired on create and update, but not on destroy:
221
+ #
222
+ # after_commit :do_zoo, :if => :persisted?
223
+ #
224
+ # Note that transactional fixtures do not play well with this feature. Please
225
+ # use the +test_after_commit+ gem to have these hooks fired in tests.
211
226
  def after_commit(*args, &block)
212
227
  options = args.last
213
228
  if options.is_a?(Hash) && options[:on]
@@ -217,6 +232,9 @@ module ActiveRecord
217
232
  set_callback(:commit, :after, *args, &block)
218
233
  end
219
234
 
235
+ # This callback is called after a create, update, or destroy are rolled back.
236
+ #
237
+ # Please check the documentation of +after_commit+ for options.
220
238
  def after_rollback(*args, &block)
221
239
  options = args.last
222
240
  if options.is_a?(Hash) && options[:on]
@@ -301,7 +319,7 @@ module ActiveRecord
301
319
  protected
302
320
 
303
321
  # Save the new record state and id of a record so it can be restored later if a transaction fails.
304
- def remember_transaction_record_state #:nodoc
322
+ def remember_transaction_record_state #:nodoc:
305
323
  @_start_transaction_state ||= {}
306
324
  @_start_transaction_state[:id] = id if has_attribute?(self.class.primary_key)
307
325
  unless @_start_transaction_state.include?(:new_record)
@@ -311,10 +329,11 @@ module ActiveRecord
311
329
  @_start_transaction_state[:destroyed] = @destroyed
312
330
  end
313
331
  @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
332
+ @_start_transaction_state[:frozen?] = @attributes.frozen?
314
333
  end
315
334
 
316
335
  # Clear the new record state and id of a record.
317
- def clear_transaction_record_state #:nodoc
336
+ def clear_transaction_record_state #:nodoc:
318
337
  if defined?(@_start_transaction_state)
319
338
  @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
320
339
  remove_instance_variable(:@_start_transaction_state) if @_start_transaction_state[:level] < 1
@@ -322,11 +341,12 @@ module ActiveRecord
322
341
  end
323
342
 
324
343
  # Restore the new record state and id of a record that was previously saved by a call to save_record_state.
325
- def restore_transaction_record_state(force = false) #:nodoc
344
+ def restore_transaction_record_state(force = false) #:nodoc:
326
345
  if defined?(@_start_transaction_state)
327
346
  @_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) - 1
328
- if @_start_transaction_state[:level] < 1
347
+ if @_start_transaction_state[:level] < 1 || force
329
348
  restore_state = remove_instance_variable(:@_start_transaction_state)
349
+ was_frozen = restore_state[:frozen?]
330
350
  @attributes = @attributes.dup if @attributes.frozen?
331
351
  @new_record = restore_state[:new_record]
332
352
  @destroyed = restore_state[:destroyed]
@@ -336,17 +356,18 @@ module ActiveRecord
336
356
  @attributes.delete(self.class.primary_key)
337
357
  @attributes_cache.delete(self.class.primary_key)
338
358
  end
359
+ @attributes.freeze if was_frozen
339
360
  end
340
361
  end
341
362
  end
342
363
 
343
364
  # Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
344
- def transaction_record_state(state) #:nodoc
365
+ def transaction_record_state(state) #:nodoc:
345
366
  @_start_transaction_state[state] if defined?(@_start_transaction_state)
346
367
  end
347
368
 
348
369
  # Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
349
- def transaction_include_action?(action) #:nodoc
370
+ def transaction_include_action?(action) #:nodoc:
350
371
  case action
351
372
  when :create
352
373
  transaction_record_state(:new_record)
@@ -0,0 +1,22 @@
1
+ module ActiveRecord
2
+ module Translation
3
+ include ActiveModel::Translation
4
+
5
+ # Set the lookup ancestors for ActiveModel.
6
+ def lookup_ancestors #:nodoc:
7
+ klass = self
8
+ classes = [klass]
9
+ return classes if klass == ActiveRecord::Base
10
+
11
+ while klass != klass.base_class
12
+ classes << klass = klass.superclass
13
+ end
14
+ classes
15
+ end
16
+
17
+ # Set the i18n scope to overwrite ActiveModel.
18
+ def i18n_scope #:nodoc:
19
+ :activerecord
20
+ end
21
+ end
22
+ end
@@ -2,8 +2,9 @@ module ActiveRecord
2
2
  module Validations
3
3
  class AssociatedValidator < ActiveModel::EachValidator
4
4
  def validate_each(record, attribute, value)
5
- return if (value.is_a?(Array) ? value : [value]).collect{ |r| r.nil? || r.valid? }.all?
6
- record.errors.add(attribute, :invalid, options.merge(:value => value))
5
+ if Array.wrap(value).reject {|r| r.marked_for_destruction? || r.valid?}.any?
6
+ record.errors.add(attribute, :invalid, options.merge(:value => value))
7
+ end
7
8
  end
8
9
  end
9
10
 
@@ -29,10 +30,10 @@ module ActiveRecord
29
30
  # validation contexts by default (+nil+), other options are <tt>:create</tt>
30
31
  # and <tt>:update</tt>.
31
32
  # * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
32
- # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
33
+ # occur (e.g. <tt>:if => :allow_validation</tt>, or <tt>:if => Proc.new { |user| user.signup_step > 2 }</tt>). The
33
34
  # method, proc or string should return or evaluate to a true or false value.
34
35
  # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
35
- # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
36
+ # not occur (e.g. <tt>:unless => :skip_validation</tt>, or <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The
36
37
  # method, proc or string should return or evaluate to a true or false value.
37
38
  def validates_associated(*attr_names)
38
39
  validates_with AssociatedValidator, _merge_attributes(attr_names)
@@ -26,7 +26,7 @@ module ActiveRecord
26
26
  relation = relation.and(table[finder_class.primary_key.to_sym].not_eq(record.send(:id))) if record.persisted?
27
27
 
28
28
  Array.wrap(options[:scope]).each do |scope_item|
29
- scope_value = record.send(scope_item)
29
+ scope_value = record.read_attribute(scope_item)
30
30
  relation = relation.and(table[scope_item].eq(scope_value))
31
31
  end
32
32
 
@@ -54,13 +54,13 @@ module ActiveRecord
54
54
 
55
55
  def build_relation(klass, table, attribute, value) #:nodoc:
56
56
  column = klass.columns_hash[attribute.to_s]
57
- value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if column.text?
57
+ value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if value && column.text?
58
58
 
59
59
  if !options[:case_sensitive] && value && column.text?
60
- # will use SQL LOWER function before comparison
61
- relation = table[attribute].lower.eq(table.lower(value))
60
+ # will use SQL LOWER function before comparison, unless it detects a case insensitive collation
61
+ relation = klass.connection.case_insensitive_comparison(table, attribute, column, value)
62
62
  else
63
- value = klass.connection.case_sensitive_modifier(value)
63
+ value = klass.connection.case_sensitive_modifier(value) if value
64
64
  relation = table[attribute].eq(value)
65
65
  end
66
66
 
@@ -81,9 +81,9 @@ module ActiveRecord
81
81
  #
82
82
  # class Person < ActiveRecord::Base
83
83
  # validates_uniqueness_of :user_name, :scope => :account_id
84
- # end
84
+ # end
85
85
  #
86
- # Or even multiple scope parameters. For example, making sure that a teacher can only be on the schedule once
86
+ # Or even multiple scope parameters. For example, making sure that a teacher can only be on the schedule once
87
87
  # per semester for a particular class.
88
88
  #
89
89
  # class TeacherSchedule < ActiveRecord::Base
@@ -105,7 +105,7 @@ module ActiveRecord
105
105
  # The method, proc or string should return or evaluate to a true or false value.
106
106
  # * <tt>:unless</tt> - Specifies a method, proc or string to call to determine if the validation should
107
107
  # not occur (e.g. <tt>:unless => :skip_validation</tt>, or
108
- # <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The method, proc or string should
108
+ # <tt>:unless => Proc.new { |user| user.signup_step <= 2 }</tt>). The method, proc or string should
109
109
  # return or evaluate to a true or false value.
110
110
  #
111
111
  # === Concurrency and integrity
@@ -1,7 +1,7 @@
1
1
  module ActiveRecord
2
2
  # = Active Record RecordInvalid
3
3
  #
4
- # Raised by <tt>save!</tt> and <tt>create!</tt> when the record is invalid. Use the
4
+ # Raised by <tt>save!</tt> and <tt>create!</tt> when the record is invalid. Use the
5
5
  # +record+ method to retrieve the record which did not validate.
6
6
  #
7
7
  # begin
@@ -1,9 +1,9 @@
1
1
  module ActiveRecord
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
- MINOR = 1
5
- TINY = 12
6
- PRE = nil
4
+ MINOR = 2
5
+ TINY = 22
6
+ PRE = "1"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
  end
data/lib/active_record.rb CHANGED
@@ -31,13 +31,25 @@ require 'active_record/version'
31
31
  module ActiveRecord
32
32
  extend ActiveSupport::Autoload
33
33
 
34
+ # ActiveRecord::SessionStore depends on the abstract store in Action Pack.
35
+ # Eager loading this class would break client code that eager loads Active
36
+ # Record standalone.
37
+ #
38
+ # Note that the Rails application generator creates an initializer specific
39
+ # for setting the session store. Thus, albeit in theory this autoload would
40
+ # not be thread-safe, in practice it is because if the application uses this
41
+ # session store its autoload happens at boot time.
42
+ autoload :SessionStore
43
+
34
44
  eager_autoload do
35
45
  autoload :ActiveRecordError, 'active_record/errors'
36
46
  autoload :ConnectionNotEstablished, 'active_record/errors'
47
+ autoload :ConnectionAdapters, 'active_record/connection_adapters/abstract_adapter'
37
48
 
38
49
  autoload :Aggregations
39
50
  autoload :Associations
40
51
  autoload :AttributeMethods
52
+ autoload :AttributeAssignment
41
53
  autoload :AutosaveAssociation
42
54
 
43
55
  autoload :Relation
@@ -49,29 +61,41 @@ module ActiveRecord
49
61
  autoload :PredicateBuilder
50
62
  autoload :SpawnMethods
51
63
  autoload :Batches
64
+ autoload :Explain
65
+ autoload :Delegation
52
66
  end
53
67
 
54
68
  autoload :Base
55
69
  autoload :Callbacks
56
70
  autoload :CounterCache
71
+ autoload :DynamicMatchers
57
72
  autoload :DynamicFinderMatch
58
73
  autoload :DynamicScopeMatch
74
+ autoload :Explain
75
+ autoload :IdentityMap
76
+ autoload :Inheritance
77
+ autoload :Integration
59
78
  autoload :Migration
60
79
  autoload :Migrator, 'active_record/migration'
61
- autoload :NamedScope
80
+ autoload :ModelSchema
62
81
  autoload :NestedAttributes
63
82
  autoload :Observer
64
83
  autoload :Persistence
65
84
  autoload :QueryCache
85
+ autoload :Querying
86
+ autoload :ReadonlyAttributes
66
87
  autoload :Reflection
88
+ autoload :Result
89
+ autoload :Sanitization
67
90
  autoload :Schema
68
91
  autoload :SchemaDumper
92
+ autoload :Scoping
69
93
  autoload :Serialization
70
- autoload :SessionStore
94
+ autoload :Store
71
95
  autoload :Timestamp
72
96
  autoload :Transactions
97
+ autoload :Translation
73
98
  autoload :Validations
74
- autoload :IdentityMap
75
99
  end
76
100
 
77
101
  module Coders
@@ -89,6 +113,8 @@ module ActiveRecord
89
113
  autoload :Read
90
114
  autoload :TimeZoneConversion
91
115
  autoload :Write
116
+ autoload :Serialization
117
+ autoload :DeprecatedUnderscoreRead
92
118
  end
93
119
  end
94
120
 
@@ -110,6 +136,15 @@ module ActiveRecord
110
136
  end
111
137
  end
112
138
 
139
+ module Scoping
140
+ extend ActiveSupport::Autoload
141
+
142
+ eager_autoload do
143
+ autoload :Named
144
+ autoload :Default
145
+ end
146
+ end
147
+
113
148
  autoload :TestCase
114
149
  autoload :TestFixtures, 'active_record/fixtures'
115
150
  end
@@ -3,7 +3,7 @@ require 'rails/generators/active_record'
3
3
  module ActiveRecord
4
4
  module Generators
5
5
  class MigrationGenerator < Base
6
- argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
6
+ argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]"
7
7
 
8
8
  def create_migration_file
9
9
  set_local_assigns!
@@ -2,14 +2,20 @@ class <%= migration_class_name %> < ActiveRecord::Migration
2
2
  <%- if migration_action == 'add' -%>
3
3
  def change
4
4
  <% attributes.each do |attribute| -%>
5
- add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %>
5
+ add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
6
+ <%- if attribute.has_index? -%>
7
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
8
+ <%- end -%>
6
9
  <%- end -%>
7
10
  end
8
11
  <%- else -%>
9
12
  def up
10
13
  <% attributes.each do |attribute| -%>
11
14
  <%- if migration_action -%>
12
- <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end %>
15
+ <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
16
+ <%- if attribute.has_index? && migration_action == 'add' -%>
17
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
18
+ <%- end -%>
13
19
  <%- end -%>
14
20
  <%- end -%>
15
21
  end
@@ -17,7 +23,10 @@ class <%= migration_class_name %> < ActiveRecord::Migration
17
23
  def down
18
24
  <% attributes.reverse.each do |attribute| -%>
19
25
  <%- if migration_action -%>
20
- <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end %>
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 -%>
21
30
  <%- end -%>
22
31
  <%- end -%>
23
32
  end
@@ -3,7 +3,7 @@ require 'rails/generators/active_record'
3
3
  module ActiveRecord
4
4
  module Generators
5
5
  class ModelGenerator < Base
6
- argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
6
+ argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]"
7
7
 
8
8
  check_class_collision
9
9
 
@@ -26,6 +26,14 @@ module ActiveRecord
26
26
  template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke
27
27
  end
28
28
 
29
+ def attributes_with_index
30
+ attributes.select { |a| a.has_index? || (a.reference? && options[:indexes]) }
31
+ end
32
+
33
+ def accessible_attributes
34
+ attributes.reject(&:reference?)
35
+ end
36
+
29
37
  hook_for :test_framework
30
38
 
31
39
  protected
@@ -2,16 +2,14 @@ class <%= migration_class_name %> < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :<%= table_name %> do |t|
4
4
  <% attributes.each do |attribute| -%>
5
- t.<%= attribute.type %> :<%= attribute.name %>
5
+ t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
6
6
  <% end -%>
7
7
  <% if options[:timestamps] %>
8
8
  t.timestamps
9
9
  <% end -%>
10
10
  end
11
- <% if options[:indexes] -%>
12
- <% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
13
- add_index :<%= table_name %>, :<%= attribute.name %>_id
14
- <% end -%>
11
+ <% attributes_with_index.each do |attribute| -%>
12
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
15
13
  <% end -%>
16
14
  end
17
15
  end
@@ -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 -%>
@@ -1,5 +1,5 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration
2
- def up
2
+ def change
3
3
  create_table :<%= session_table_name %> do |t|
4
4
  t.string :session_id, :null => false
5
5
  t.text :data
@@ -9,8 +9,4 @@ class <%= migration_class_name %> < ActiveRecord::Migration
9
9
  add_index :<%= session_table_name %>, :session_id
10
10
  add_index :<%= session_table_name %>, :updated_at
11
11
  end
12
-
13
- def down
14
- drop_table :<%= session_table_name %>
15
- end
16
12
  end