activerecord 3.1.0.beta1 → 3.1.0.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 (35) hide show
  1. data/CHANGELOG +123 -30
  2. data/README.rdoc +2 -2
  3. data/lib/active_record/associations.rb +10 -9
  4. data/lib/active_record/associations/alias_tracker.rb +2 -2
  5. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
  6. data/lib/active_record/associations/builder/singular_association.rb +19 -6
  7. data/lib/active_record/associations/collection_association.rb +61 -52
  8. data/lib/active_record/associations/collection_proxy.rb +30 -3
  9. data/lib/active_record/associations/has_one_association.rb +1 -1
  10. data/lib/active_record/associations/join_dependency/join_association.rb +3 -3
  11. data/lib/active_record/associations/join_helper.rb +1 -1
  12. data/lib/active_record/associations/singular_association.rb +13 -12
  13. data/lib/active_record/associations/through_association.rb +4 -1
  14. data/lib/active_record/base.rb +95 -46
  15. data/lib/active_record/connection_adapters/abstract/database_statements.rb +1 -9
  16. data/lib/active_record/connection_adapters/column.rb +1 -1
  17. data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -3
  18. data/lib/active_record/connection_adapters/postgresql_adapter.rb +28 -26
  19. data/lib/active_record/fixtures.rb +294 -339
  20. data/lib/active_record/identity_map.rb +34 -8
  21. data/lib/active_record/locking/optimistic.rb +16 -16
  22. data/lib/active_record/locking/pessimistic.rb +2 -2
  23. data/lib/active_record/observer.rb +3 -3
  24. data/lib/active_record/persistence.rb +1 -1
  25. data/lib/active_record/railties/controller_runtime.rb +10 -1
  26. data/lib/active_record/railties/databases.rake +9 -9
  27. data/lib/active_record/relation/calculations.rb +5 -6
  28. data/lib/active_record/relation/finder_methods.rb +9 -4
  29. data/lib/active_record/serialization.rb +1 -1
  30. data/lib/active_record/session_store.rb +4 -2
  31. data/lib/active_record/test_case.rb +7 -0
  32. data/lib/active_record/validations.rb +3 -3
  33. data/lib/active_record/version.rb +1 -1
  34. data/lib/rails/generators/active_record/model/templates/migration.rb +1 -1
  35. metadata +6 -6
@@ -12,10 +12,36 @@ module ActiveRecord
12
12
  # In order to enable IdentityMap, set <tt>config.active_record.identity_map = true</tt>
13
13
  # in your <tt>config/application.rb</tt> file.
14
14
  #
15
- # IdentityMap is disabled by default.
15
+ # IdentityMap is disabled by default and still in development (i.e. use it with care).
16
+ #
17
+ # == Associations
18
+ #
19
+ # Active Record Identity Map does not track associations yet. For example:
20
+ #
21
+ # comment = @post.comments.first
22
+ # comment.post = nil
23
+ # @post.comments.include?(comment) #=> true
24
+ #
25
+ # Ideally, the example above would return false, removing the comment object from the
26
+ # post association when the association is nullified. This may cause side effects, as
27
+ # in the situation below, if Identity Map is enabled:
28
+ #
29
+ # Post.has_many :comments, :dependent => :destroy
30
+ #
31
+ # comment = @post.comments.first
32
+ # comment.post = nil
33
+ # comment.save
34
+ # Post.destroy(@post.id)
35
+ #
36
+ # Without using Identity Map, the code above will destroy the @post object leaving
37
+ # the comment object intact. However, once we enable Identity Map, the post loaded
38
+ # by Post.destroy is exactly the same object as the object @post. As the object @post
39
+ # still has the comment object in @post.comments, once Identity Map is enabled, the
40
+ # comment object will be accidently removed.
41
+ #
42
+ # This inconsistency is meant to be fixed in future Rails releases.
16
43
  #
17
44
  module IdentityMap
18
- extend ActiveSupport::Concern
19
45
 
20
46
  class << self
21
47
  def enabled=(flag)
@@ -49,11 +75,11 @@ module ActiveRecord
49
75
  end
50
76
 
51
77
  def get(klass, primary_key)
52
- record = repository[klass.symbolized_base_class][primary_key]
78
+ record = repository[klass.symbolized_sti_name][primary_key]
53
79
 
54
80
  if record.is_a?(klass)
55
81
  ActiveSupport::Notifications.instrument("identity.active_record",
56
- :line => "From Identity Map (id: #{primary_key})",
82
+ :line => "From Identity Map (id: #{primary_key})",
57
83
  :name => "#{klass} Loaded",
58
84
  :connection_id => object_id)
59
85
 
@@ -64,15 +90,15 @@ module ActiveRecord
64
90
  end
65
91
 
66
92
  def add(record)
67
- repository[record.class.symbolized_base_class][record.id] = record
93
+ repository[record.class.symbolized_sti_name][record.id] = record
68
94
  end
69
95
 
70
96
  def remove(record)
71
- repository[record.class.symbolized_base_class].delete(record.id)
97
+ repository[record.class.symbolized_sti_name].delete(record.id)
72
98
  end
73
99
 
74
- def remove_by_id(symbolized_base_class, id)
75
- repository[symbolized_base_class].delete(id)
100
+ def remove_by_id(symbolized_sti_name, id)
101
+ repository[symbolized_sti_name].delete(id)
76
102
  end
77
103
 
78
104
  def clear
@@ -3,16 +3,17 @@ module ActiveRecord
3
3
  # == What is Optimistic Locking
4
4
  #
5
5
  # Optimistic locking allows multiple users to access the same record for edits, and assumes a minimum of
6
- # conflicts with the data. It does this by checking whether another process has made changes to a record since
7
- # it was opened, an ActiveRecord::StaleObjectError is thrown if that has occurred and the update is ignored.
6
+ # conflicts with the data. It does this by checking whether another process has made changes to a record since
7
+ # it was opened, an <tt>ActiveRecord::StaleObjectError</tt> exception is thrown if that has occurred
8
+ # and the update is ignored.
8
9
  #
9
- # Check out ActiveRecord::Locking::Pessimistic for an alternative.
10
+ # Check out <tt>ActiveRecord::Locking::Pessimistic</tt> for an alternative.
10
11
  #
11
12
  # == Usage
12
13
  #
13
- # Active Records support optimistic locking if the field <tt>lock_version</tt> is present. Each update to the
14
- # record increments the lock_version column and the locking facilities ensure that records instantiated twice
15
- # will let the last one saved raise a StaleObjectError if the first was also updated. Example:
14
+ # Active Records support optimistic locking if the field +lock_version+ is present. Each update to the
15
+ # record increments the +lock_version+ column and the locking facilities ensure that records instantiated twice
16
+ # will let the last one saved raise a +StaleObjectError+ if the first was also updated. Example:
16
17
  #
17
18
  # p1 = Person.find(1)
18
19
  # p2 = Person.find(1)
@@ -36,10 +37,10 @@ module ActiveRecord
36
37
  # You're then responsible for dealing with the conflict by rescuing the exception and either rolling back, merging,
37
38
  # or otherwise apply the business logic needed to resolve the conflict.
38
39
  #
39
- # You must ensure that your database schema defaults the lock_version column to 0.
40
+ # You must ensure that your database schema defaults the +lock_version+ column to 0.
40
41
  #
41
42
  # This behavior can be turned off by setting <tt>ActiveRecord::Base.lock_optimistically = false</tt>.
42
- # To override the name of the lock_version column, invoke the <tt>set_locking_column</tt> method.
43
+ # To override the name of the +lock_version+ column, invoke the <tt>set_locking_column</tt> method.
43
44
  # This method uses the same syntax as <tt>set_table_name</tt>
44
45
  module Optimistic
45
46
  extend ActiveSupport::Concern
@@ -68,9 +69,9 @@ module ActiveRecord
68
69
  result = super
69
70
 
70
71
  # If the locking column has no default value set,
71
- # start the lock version at zero. Note we can't use
72
- # locking_enabled? at this point as @attributes may
73
- # not have been initialized yet
72
+ # start the lock version at zero. Note we can't use
73
+ # <tt>locking_enabled?</tt> at this point as
74
+ # <tt>@attributes</tt> may not have been initialized yet.
74
75
 
75
76
  if lock_optimistically && result.include?(self.class.locking_column)
76
77
  result[self.class.locking_column] ||= 0
@@ -94,7 +95,7 @@ module ActiveRecord
94
95
  relation = self.class.unscoped
95
96
 
96
97
  stmt = relation.where(
97
- relation.table[self.class.primary_key].eq(quoted_id).and(
98
+ relation.table[self.class.primary_key].eq(id).and(
98
99
  relation.table[lock_col].eq(quote_value(previous_lock_value))
99
100
  )
100
101
  ).arel.compile_update(arel_attributes_values(false, false, attribute_names))
@@ -137,10 +138,9 @@ module ActiveRecord
137
138
  module ClassMethods
138
139
  DEFAULT_LOCKING_COLUMN = 'lock_version'
139
140
 
140
- # Is optimistic locking enabled for this table? Returns true if the
141
- # +lock_optimistically+ flag is set to true (which it is, by default)
142
- # and the table includes the +locking_column+ column (defaults to
143
- # +lock_version+).
141
+ # Returns true if the +lock_optimistically+ flag is set to true
142
+ # (which it is, by default) and the table includes the
143
+ # +locking_column+ column (defaults to +lock_version+).
144
144
  def locking_enabled?
145
145
  lock_optimistically && columns_hash[locking_column]
146
146
  end
@@ -3,7 +3,7 @@ module ActiveRecord
3
3
  # Locking::Pessimistic provides support for row-level locking using
4
4
  # SELECT ... FOR UPDATE and other lock types.
5
5
  #
6
- # Pass <tt>:lock => true</tt> to ActiveRecord::Base.find to obtain an exclusive
6
+ # Pass <tt>:lock => true</tt> to <tt>ActiveRecord::Base.find</tt> to obtain an exclusive
7
7
  # lock on the selected rows:
8
8
  # # select * from accounts where id=1 for update
9
9
  # Account.find(1, :lock => true)
@@ -21,7 +21,7 @@ module ActiveRecord
21
21
  # yuko.save!
22
22
  # end
23
23
  #
24
- # You can also use ActiveRecord::Base#lock! method to lock one record by id.
24
+ # You can also use <tt>ActiveRecord::Base#lock!</tt> method to lock one record by id.
25
25
  # This may be better if you don't need to lock every row. Example:
26
26
  #
27
27
  # Account.transaction do
@@ -11,7 +11,7 @@ module ActiveRecord
11
11
  #
12
12
  # class CommentObserver < ActiveRecord::Observer
13
13
  # def after_save(comment)
14
- # Notifications.deliver_comment("admin@do.com", "New comment was posted", comment)
14
+ # Notifications.comment("admin@do.com", "New comment was posted", comment).deliver
15
15
  # end
16
16
  # end
17
17
  #
@@ -110,8 +110,8 @@ module ActiveRecord
110
110
  next unless respond_to?(callback)
111
111
  callback_meth = :"_notify_#{observer_name}_for_#{callback}"
112
112
  unless klass.respond_to?(callback_meth)
113
- klass.send(:define_method, callback_meth) do
114
- observer.send(callback, self)
113
+ klass.send(:define_method, callback_meth) do |&block|
114
+ observer.send(callback, self, &block)
115
115
  end
116
116
  klass.send(callback, callback_meth)
117
117
  end
@@ -146,7 +146,7 @@ module ActiveRecord
146
146
  # will fail and false will be returned.
147
147
  #
148
148
  # When updating model attributes, mass-assignment security protection is respected.
149
- # If no +:as+ option is supplied then the +:default+ scope will be used.
149
+ # If no +:as+ option is supplied then the +:default+ role will be used.
150
150
  # If you want to bypass the protection given by +attr_protected+ and
151
151
  # +attr_accessible+ then you can do so using the +:without_protection+ option.
152
152
  def update_attributes(attributes, options = {})
@@ -1,14 +1,23 @@
1
1
  require 'active_support/core_ext/module/attr_internal'
2
+ require 'active_record/log_subscriber'
2
3
 
3
4
  module ActiveRecord
4
5
  module Railties
5
- module ControllerRuntime
6
+ module ControllerRuntime #:nodoc:
6
7
  extend ActiveSupport::Concern
7
8
 
8
9
  protected
9
10
 
10
11
  attr_internal :db_runtime
11
12
 
13
+ def process_action(action, *args)
14
+ # We also need to reset the runtime before each action
15
+ # because of queries in middleware or in cases we are streaming
16
+ # and it won't be cleaned up by the method below.
17
+ ActiveRecord::LogSubscriber.reset_runtime
18
+ super
19
+ end
20
+
12
21
  def cleanup_view_runtime
13
22
  if ActiveRecord::Base.connected?
14
23
  db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
@@ -203,18 +203,18 @@ db_namespace = namespace :db do
203
203
  # only files matching "20091231235959_some_name.rb" pattern
204
204
  if match_data = /^(\d{14})_(.+)\.rb$/.match(file)
205
205
  status = db_list.delete(match_data[1]) ? 'up' : 'down'
206
- file_list << [status, match_data[1], match_data[2]]
206
+ file_list << [status, match_data[1], match_data[2].humanize]
207
207
  end
208
208
  end
209
+ db_list.map! do |version|
210
+ ['up', version, '********** NO FILE **********']
211
+ end
209
212
  # output
210
213
  puts "\ndatabase: #{config['database']}\n\n"
211
214
  puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
212
215
  puts "-" * 50
213
- file_list.each do |file|
214
- puts "#{file[0].center(8)} #{file[1].ljust(14)} #{file[2].humanize}"
215
- end
216
- db_list.each do |version|
217
- puts "#{'up'.center(8)} #{version.ljust(14)} *** NO FILE ***"
216
+ (db_list + file_list).sort_by {|migration| migration[1]}.each do |migration|
217
+ puts "#{migration[0].center(8)} #{migration[1].ljust(14)} #{migration[2]}"
218
218
  end
219
219
  puts
220
220
  end
@@ -305,7 +305,7 @@ db_namespace = namespace :db do
305
305
  fixtures_dir = File.join [base_dir, ENV['FIXTURES_DIR']].compact
306
306
 
307
307
  (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir["#{fixtures_dir}/**/*.{yml,csv}"].map {|f| f[(fixtures_dir.size + 1)..-5] }).each do |fixture_file|
308
- Fixtures.create_fixtures(fixtures_dir, fixture_file)
308
+ ActiveRecord::Fixtures.create_fixtures(fixtures_dir, fixture_file)
309
309
  end
310
310
  end
311
311
 
@@ -316,13 +316,13 @@ db_namespace = namespace :db do
316
316
  label, id = ENV['LABEL'], ENV['ID']
317
317
  raise 'LABEL or ID required' if label.blank? && id.blank?
318
318
 
319
- puts %Q(The fixture ID for "#{label}" is #{Fixtures.identify(label)}.) if label
319
+ puts %Q(The fixture ID for "#{label}" is #{ActiveRecord::Fixtures.identify(label)}.) if label
320
320
 
321
321
  base_dir = ENV['FIXTURES_PATH'] ? File.join(Rails.root, ENV['FIXTURES_PATH']) : File.join(Rails.root, 'test', 'fixtures')
322
322
  Dir["#{base_dir}/**/*.yml"].each do |file|
323
323
  if data = YAML::load(ERB.new(IO.read(file)).result)
324
324
  data.keys.each do |key|
325
- key_id = Fixtures.identify(key)
325
+ key_id = ActiveRecord::Fixtures.identify(key)
326
326
 
327
327
  if key == label || key_id == id.to_i
328
328
  puts "#{file}: #{key} (#{key_id})"
@@ -146,7 +146,7 @@ module ActiveRecord
146
146
  if options.except(:distinct).present?
147
147
  apply_finder_options(options.except(:distinct)).calculate(operation, column_name, :distinct => options[:distinct])
148
148
  else
149
- if eager_loading? || includes_values.present?
149
+ if eager_loading? || (includes_values.present? && references_eager_loaded_tables?)
150
150
  construct_relation_for_association_calculations.calculate(operation, column_name, options)
151
151
  else
152
152
  perform_calculation(operation, column_name, options)
@@ -161,21 +161,20 @@ module ActiveRecord
161
161
  def perform_calculation(operation, column_name, options = {})
162
162
  operation = operation.to_s.downcase
163
163
 
164
- distinct = nil
164
+ distinct = options[:distinct]
165
165
 
166
166
  if operation == "count"
167
167
  column_name ||= (select_for_count || :all)
168
168
 
169
169
  unless arel.ast.grep(Arel::Nodes::OuterJoin).empty?
170
170
  distinct = true
171
- column_name = primary_key if column_name == :all
172
171
  end
173
172
 
173
+ column_name = primary_key if column_name == :all && distinct
174
+
174
175
  distinct = nil if column_name =~ /\s*DISTINCT\s+/i
175
176
  end
176
177
 
177
- distinct = options[:distinct] || distinct
178
-
179
178
  if @group_values.any?
180
179
  execute_grouped_calculation(operation, column_name, distinct)
181
180
  else
@@ -197,7 +196,7 @@ module ActiveRecord
197
196
 
198
197
  def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
199
198
  # Postgresql doesn't like ORDER BY when there are no GROUP BY
200
- relation = except(:order)
199
+ relation = reorder(nil)
201
200
 
202
201
  if operation == "count" && (relation.limit_value || relation.offset_value)
203
202
  # Shortcut when limit is zero.
@@ -226,7 +226,7 @@ module ActiveRecord
226
226
  end
227
227
 
228
228
  def apply_join_dependency(relation, join_dependency)
229
- for association in join_dependency.join_associations
229
+ join_dependency.join_associations.each do |association|
230
230
  relation = association.join_relation(relation)
231
231
  end
232
232
 
@@ -264,6 +264,7 @@ module ActiveRecord
264
264
  end
265
265
 
266
266
  def find_or_instantiator_by_attributes(match, attributes, *args)
267
+ options = args.size > 1 && args.last(2).all?{ |a| a.is_a?(Hash) } ? args.extract_options! : {}
267
268
  protected_attributes_for_create, unprotected_attributes_for_create = {}, {}
268
269
  args.each_with_index do |arg, i|
269
270
  if arg.is_a?(Hash)
@@ -278,8 +279,7 @@ module ActiveRecord
278
279
  record = where(conditions).first
279
280
 
280
281
  unless record
281
- record = @klass.new do |r|
282
- r.assign_attributes(protected_attributes_for_create)
282
+ record = @klass.new(protected_attributes_for_create, options) do |r|
283
283
  r.assign_attributes(unprotected_attributes_for_create, :without_protection => true)
284
284
  end
285
285
  yield(record) if block_given?
@@ -375,7 +375,12 @@ module ActiveRecord
375
375
  if loaded?
376
376
  @records.last
377
377
  else
378
- @last ||= reverse_order.limit(1).to_a[0]
378
+ @last ||=
379
+ if offset_value || limit_value
380
+ to_a.last
381
+ else
382
+ reverse_order.limit(1).to_a[0]
383
+ end
379
384
  end
380
385
  end
381
386
 
@@ -37,7 +37,7 @@ module ActiveRecord #:nodoc:
37
37
  include_has_options = include_associations.is_a?(Hash)
38
38
  associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
39
39
 
40
- for association in associations
40
+ associations.each do |association|
41
41
  records = case self.class.reflect_on_association(association).macro
42
42
  when :has_many, :has_and_belongs_to_many
43
43
  send(association).to_a
@@ -40,7 +40,7 @@ module ActiveRecord
40
40
  # You must implement these methods:
41
41
  #
42
42
  # self.find_by_session_id(session_id)
43
- # initialize(hash_of_session_id_and_data)
43
+ # initialize(hash_of_session_id_and_data, options_hash = {})
44
44
  # attr_reader :session_id
45
45
  # attr_accessor :data
46
46
  # save
@@ -83,6 +83,8 @@ module ActiveRecord
83
83
  cattr_accessor :data_column_name
84
84
  self.data_column_name = 'data'
85
85
 
86
+ attr_accessible :session_id, :data, :marshaled_data
87
+
86
88
  before_save :marshal_data!
87
89
  before_save :raise_on_session_data_overflow!
88
90
 
@@ -123,7 +125,7 @@ module ActiveRecord
123
125
  end
124
126
  end
125
127
 
126
- def initialize(attributes = nil)
128
+ def initialize(attributes = nil, options = {})
127
129
  @data = nil
128
130
  super
129
131
  end
@@ -13,6 +13,13 @@ module ActiveRecord
13
13
  ActiveRecord::IdentityMap.clear
14
14
  end
15
15
 
16
+ # Backport skip to Ruby 1.8. test/unit doesn't support it, so just
17
+ # make it a noop.
18
+ unless instance_methods.map(&:to_s).include?("skip")
19
+ def skip(message)
20
+ end
21
+ end
22
+
16
23
  def assert_date_from_db(expected, actual, message = nil)
17
24
  # SybaseAdapter doesn't have a separate column type just for dates,
18
25
  # so the time is in the string and incorrectly formatted
@@ -32,11 +32,11 @@ module ActiveRecord
32
32
  module ClassMethods
33
33
  # Creates an object just like Base.create but calls <tt>save!</tt> instead of +save+
34
34
  # so an exception is raised if the record is invalid.
35
- def create!(attributes = nil, &block)
35
+ def create!(attributes = nil, options = {}, &block)
36
36
  if attributes.is_a?(Array)
37
- attributes.collect { |attr| create!(attr, &block) }
37
+ attributes.collect { |attr| create!(attr, options, &block) }
38
38
  else
39
- object = new(attributes)
39
+ object = new(attributes, options)
40
40
  yield(object) if block_given?
41
41
  object.save!
42
42
  object
@@ -3,7 +3,7 @@ module ActiveRecord
3
3
  MAJOR = 3
4
4
  MINOR = 1
5
5
  TINY = 0
6
- PRE = "beta1"
6
+ PRE = "rc1"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
  end
@@ -1,7 +1,7 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :<%= table_name %> do |t|
4
- <% for attribute in attributes -%>
4
+ <% attributes.each do |attribute| -%>
5
5
  t.<%= attribute.type %> :<%= attribute.name %>
6
6
  <% end -%>
7
7
  <% if options[:timestamps] %>
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 3.1.0.beta1
5
+ version: 3.1.0.rc1
6
6
  platform: ruby
7
7
  authors:
8
8
  - David Heinemeier Hansson
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-04 00:00:00 -05:00
13
+ date: 2011-05-21 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -21,7 +21,7 @@ dependencies:
21
21
  requirements:
22
22
  - - "="
23
23
  - !ruby/object:Gem::Version
24
- version: 3.1.0.beta1
24
+ version: 3.1.0.rc1
25
25
  type: :runtime
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  requirements:
33
33
  - - "="
34
34
  - !ruby/object:Gem::Version
35
- version: 3.1.0.beta1
35
+ version: 3.1.0.rc1
36
36
  type: :runtime
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - ~>
45
45
  - !ruby/object:Gem::Version
46
- version: 2.1.0
46
+ version: 2.1.1
47
47
  type: :runtime
48
48
  version_requirements: *id003
49
49
  - !ruby/object:Gem::Dependency
@@ -217,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
217
217
  version: 1.3.1
218
218
  requirements: []
219
219
 
220
- rubyforge_project: activerecord
220
+ rubyforge_project:
221
221
  rubygems_version: 1.6.2
222
222
  signing_key:
223
223
  specification_version: 3