activerecord 3.0.0.beta4 → 3.0.0.rc

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 (69) hide show
  1. data/CHANGELOG +267 -254
  2. data/README.rdoc +222 -0
  3. data/examples/performance.rb +9 -9
  4. data/lib/active_record/aggregations.rb +3 -4
  5. data/lib/active_record/association_preload.rb +15 -10
  6. data/lib/active_record/associations.rb +54 -37
  7. data/lib/active_record/associations/association_collection.rb +43 -17
  8. data/lib/active_record/associations/association_proxy.rb +2 -0
  9. data/lib/active_record/associations/belongs_to_association.rb +1 -0
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -0
  11. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +22 -7
  12. data/lib/active_record/associations/has_many_association.rb +6 -1
  13. data/lib/active_record/associations/has_many_through_association.rb +1 -0
  14. data/lib/active_record/associations/has_one_association.rb +1 -0
  15. data/lib/active_record/associations/has_one_through_association.rb +1 -0
  16. data/lib/active_record/associations/through_association_scope.rb +3 -2
  17. data/lib/active_record/attribute_methods.rb +1 -0
  18. data/lib/active_record/autosave_association.rb +4 -6
  19. data/lib/active_record/base.rb +106 -240
  20. data/lib/active_record/callbacks.rb +4 -25
  21. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +22 -29
  22. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +2 -8
  23. data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -2
  24. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +10 -0
  25. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +56 -7
  26. data/lib/active_record/connection_adapters/abstract_adapter.rb +10 -18
  27. data/lib/active_record/connection_adapters/mysql_adapter.rb +2 -2
  28. data/lib/active_record/connection_adapters/postgresql_adapter.rb +65 -69
  29. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +19 -6
  30. data/lib/active_record/connection_adapters/sqlite_adapter.rb +20 -46
  31. data/lib/active_record/counter_cache.rb +14 -4
  32. data/lib/active_record/dynamic_finder_match.rb +9 -0
  33. data/lib/active_record/dynamic_scope_match.rb +7 -0
  34. data/lib/active_record/errors.rb +3 -0
  35. data/lib/active_record/fixtures.rb +5 -6
  36. data/lib/active_record/locale/en.yml +1 -1
  37. data/lib/active_record/locking/optimistic.rb +1 -0
  38. data/lib/active_record/log_subscriber.rb +48 -0
  39. data/lib/active_record/migration.rb +64 -37
  40. data/lib/active_record/named_scope.rb +33 -19
  41. data/lib/active_record/nested_attributes.rb +17 -13
  42. data/lib/active_record/observer.rb +13 -6
  43. data/lib/active_record/persistence.rb +55 -22
  44. data/lib/active_record/query_cache.rb +1 -0
  45. data/lib/active_record/railtie.rb +14 -8
  46. data/lib/active_record/railties/controller_runtime.rb +2 -2
  47. data/lib/active_record/railties/databases.rake +63 -33
  48. data/lib/active_record/reflection.rb +46 -28
  49. data/lib/active_record/relation.rb +38 -24
  50. data/lib/active_record/relation/finder_methods.rb +5 -5
  51. data/lib/active_record/relation/predicate_builder.rb +2 -4
  52. data/lib/active_record/relation/query_methods.rb +134 -115
  53. data/lib/active_record/relation/spawn_methods.rb +1 -1
  54. data/lib/active_record/schema.rb +2 -0
  55. data/lib/active_record/schema_dumper.rb +15 -12
  56. data/lib/active_record/serialization.rb +2 -0
  57. data/lib/active_record/session_store.rb +93 -79
  58. data/lib/active_record/test_case.rb +3 -0
  59. data/lib/active_record/timestamp.rb +49 -29
  60. data/lib/active_record/transactions.rb +5 -2
  61. data/lib/active_record/validations.rb +5 -2
  62. data/lib/active_record/validations/associated.rb +1 -1
  63. data/lib/active_record/validations/uniqueness.rb +1 -1
  64. data/lib/active_record/version.rb +1 -1
  65. data/lib/rails/generators/active_record/migration/templates/migration.rb +12 -6
  66. data/lib/rails/generators/active_record/model/model_generator.rb +1 -1
  67. metadata +27 -14
  68. data/README +0 -351
  69. data/lib/active_record/railties/log_subscriber.rb +0 -32
@@ -11,7 +11,8 @@ module ActiveRecord
11
11
  included do
12
12
  define_callbacks :commit, :rollback, :terminator => "result == false", :scope => [:kind, :name]
13
13
  end
14
-
14
+ # = Active Record Transactions
15
+ #
15
16
  # Transactions are protective blocks where SQL statements are only permanent
16
17
  # if they can all succeed as one atomic action. The classic example is a
17
18
  # transfer between two accounts where you can only have a deposit if the
@@ -19,7 +20,8 @@ module ActiveRecord
19
20
  # the database and guard the data against program errors or database
20
21
  # break-downs. So basically you should use transaction blocks whenever you
21
22
  # have a number of statements that must be executed together or not at all.
22
- # Example:
23
+ #
24
+ # For example:
23
25
  #
24
26
  # ActiveRecord::Base.transaction do
25
27
  # david.withdrawal(100)
@@ -320,6 +322,7 @@ module ActiveRecord
320
322
  if @_start_transaction_state[:level] < 1
321
323
  restore_state = remove_instance_variable(:@_start_transaction_state)
322
324
  if restore_state
325
+ @attributes = @attributes.dup if @attributes.frozen?
323
326
  @new_record = restore_state[:new_record]
324
327
  @destroyed = restore_state[:destroyed]
325
328
  if restore_state[:id]
@@ -1,6 +1,9 @@
1
1
  module ActiveRecord
2
+ # = Active Record Validations
3
+ #
2
4
  # Raised by <tt>save!</tt> and <tt>create!</tt> when the record is invalid. Use the
3
5
  # +record+ method to retrieve the record which did not validate.
6
+ #
4
7
  # begin
5
8
  # complex_operation_that_calls_save!_internally
6
9
  # rescue ActiveRecord::RecordInvalid => invalid
@@ -49,12 +52,12 @@ module ActiveRecord
49
52
  # Runs all the specified validations and returns true if no errors were added otherwise false.
50
53
  def valid?(context = nil)
51
54
  context ||= (new_record? ? :create : :update)
52
- super(context)
55
+ output = super(context)
53
56
 
54
57
  deprecated_callback_method(:validate)
55
58
  deprecated_callback_method(:"validate_on_#{context}")
56
59
 
57
- errors.empty?
60
+ errors.empty? && output
58
61
  end
59
62
 
60
63
  protected
@@ -3,7 +3,7 @@ module ActiveRecord
3
3
  class AssociatedValidator < ActiveModel::EachValidator
4
4
  def validate_each(record, attribute, value)
5
5
  return if (value.is_a?(Array) ? value : [value]).collect{ |r| r.nil? || r.valid? }.all?
6
- record.errors.add(attribute, :invalid, :default => options[:message], :value => value)
6
+ record.errors.add(attribute, :invalid, options.merge(:value => value))
7
7
  end
8
8
  end
9
9
 
@@ -32,7 +32,7 @@ module ActiveRecord
32
32
  end
33
33
 
34
34
  if relation.exists?
35
- record.errors.add(attribute, :taken, :default => options[:message], :value => value)
35
+ record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
36
36
  end
37
37
  end
38
38
 
@@ -3,7 +3,7 @@ module ActiveRecord
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
5
  TINY = 0
6
- BUILD = "beta4"
6
+ BUILD = "rc"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, BUILD].join('.')
9
9
  end
@@ -1,11 +1,17 @@
1
1
  class <%= migration_class_name %> < ActiveRecord::Migration
2
- def self.up<% attributes.each do |attribute| %>
3
- <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end -%>
4
- <%- end %>
2
+ def self.up
3
+ <% attributes.each do |attribute| -%>
4
+ <%- if migration_action -%>
5
+ <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><% end %>
6
+ <%- end -%>
7
+ <%- end -%>
5
8
  end
6
9
 
7
- def self.down<% attributes.reverse.each do |attribute| %>
8
- <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end -%>
9
- <%- end %>
10
+ def self.down
11
+ <% attributes.reverse.each do |attribute| -%>
12
+ <%- if migration_action -%>
13
+ <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><% end %>
14
+ <%- end -%>
15
+ <%- end -%>
10
16
  end
11
17
  end
@@ -22,7 +22,7 @@ module ActiveRecord
22
22
 
23
23
  def create_module_file
24
24
  return if class_path.empty?
25
- template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb")
25
+ template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke
26
26
  end
27
27
 
28
28
  hook_for :test_framework
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 7712042
4
5
  prerelease: true
5
6
  segments:
6
7
  - 3
7
8
  - 0
8
9
  - 0
9
- - beta4
10
- version: 3.0.0.beta4
10
+ - rc
11
+ version: 3.0.0.rc
11
12
  platform: ruby
12
13
  authors:
13
14
  - David Heinemeier Hansson
@@ -15,46 +16,52 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2010-06-08 00:00:00 -04:00
19
+ date: 2010-07-26 00:00:00 -05:00
19
20
  default_executable:
20
21
  dependencies:
21
22
  - !ruby/object:Gem::Dependency
22
23
  name: activesupport
23
24
  prerelease: false
24
25
  requirement: &id001 !ruby/object:Gem::Requirement
26
+ none: false
25
27
  requirements:
26
28
  - - "="
27
29
  - !ruby/object:Gem::Version
30
+ hash: 7712042
28
31
  segments:
29
32
  - 3
30
33
  - 0
31
34
  - 0
32
- - beta4
33
- version: 3.0.0.beta4
35
+ - rc
36
+ version: 3.0.0.rc
34
37
  type: :runtime
35
38
  version_requirements: *id001
36
39
  - !ruby/object:Gem::Dependency
37
40
  name: activemodel
38
41
  prerelease: false
39
42
  requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
40
44
  requirements:
41
45
  - - "="
42
46
  - !ruby/object:Gem::Version
47
+ hash: 7712042
43
48
  segments:
44
49
  - 3
45
50
  - 0
46
51
  - 0
47
- - beta4
48
- version: 3.0.0.beta4
52
+ - rc
53
+ version: 3.0.0.rc
49
54
  type: :runtime
50
55
  version_requirements: *id002
51
56
  - !ruby/object:Gem::Dependency
52
57
  name: arel
53
58
  prerelease: false
54
59
  requirement: &id003 !ruby/object:Gem::Requirement
60
+ none: false
55
61
  requirements:
56
62
  - - ~>
57
63
  - !ruby/object:Gem::Version
64
+ hash: 15
58
65
  segments:
59
66
  - 0
60
67
  - 4
@@ -66,14 +73,16 @@ dependencies:
66
73
  name: tzinfo
67
74
  prerelease: false
68
75
  requirement: &id004 !ruby/object:Gem::Requirement
76
+ none: false
69
77
  requirements:
70
78
  - - ~>
71
79
  - !ruby/object:Gem::Version
80
+ hash: 63
72
81
  segments:
73
82
  - 0
74
83
  - 3
75
- - 16
76
- version: 0.3.16
84
+ - 22
85
+ version: 0.3.22
77
86
  type: :runtime
78
87
  version_requirements: *id004
79
88
  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.
@@ -83,10 +92,10 @@ executables: []
83
92
  extensions: []
84
93
 
85
94
  extra_rdoc_files:
86
- - README
95
+ - README.rdoc
87
96
  files:
88
97
  - CHANGELOG
89
- - README
98
+ - README.rdoc
90
99
  - examples/associations.png
91
100
  - examples/performance.rb
92
101
  - examples/simple.rb
@@ -135,6 +144,7 @@ files:
135
144
  - lib/active_record/locale/en.yml
136
145
  - lib/active_record/locking/optimistic.rb
137
146
  - lib/active_record/locking/pessimistic.rb
147
+ - lib/active_record/log_subscriber.rb
138
148
  - lib/active_record/migration.rb
139
149
  - lib/active_record/named_scope.rb
140
150
  - lib/active_record/nested_attributes.rb
@@ -144,7 +154,6 @@ files:
144
154
  - lib/active_record/railtie.rb
145
155
  - lib/active_record/railties/controller_runtime.rb
146
156
  - lib/active_record/railties/databases.rake
147
- - lib/active_record/railties/log_subscriber.rb
148
157
  - lib/active_record/reflection.rb
149
158
  - lib/active_record/relation/batches.rb
150
159
  - lib/active_record/relation/calculations.rb
@@ -184,22 +193,26 @@ licenses: []
184
193
  post_install_message:
185
194
  rdoc_options:
186
195
  - --main
187
- - README
196
+ - README.rdoc
188
197
  require_paths:
189
198
  - lib
190
199
  required_ruby_version: !ruby/object:Gem::Requirement
200
+ none: false
191
201
  requirements:
192
202
  - - ">="
193
203
  - !ruby/object:Gem::Version
204
+ hash: 57
194
205
  segments:
195
206
  - 1
196
207
  - 8
197
208
  - 7
198
209
  version: 1.8.7
199
210
  required_rubygems_version: !ruby/object:Gem::Requirement
211
+ none: false
200
212
  requirements:
201
213
  - - ">"
202
214
  - !ruby/object:Gem::Version
215
+ hash: 25
203
216
  segments:
204
217
  - 1
205
218
  - 3
@@ -208,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
221
  requirements: []
209
222
 
210
223
  rubyforge_project: activerecord
211
- rubygems_version: 1.3.6
224
+ rubygems_version: 1.3.7
212
225
  signing_key:
213
226
  specification_version: 3
214
227
  summary: Object-relational mapper framework (part of Rails).
data/README DELETED
@@ -1,351 +0,0 @@
1
- = Active Record -- Object-relation mapping put on rails
2
-
3
- Active Record connects business objects and database tables to create a persistable
4
- domain model where logic and data are presented in one wrapping. It's an implementation
5
- of the object-relational mapping (ORM) pattern[http://www.martinfowler.com/eaaCatalog/activeRecord.html]
6
- by the same name as described by Martin Fowler:
7
-
8
- "An object that wraps a row in a database table or view, encapsulates
9
- the database access, and adds domain logic on that data."
10
-
11
- Active Record's main contribution to the pattern is to relieve the original of two stunting problems:
12
- lack of associations and inheritance. By adding a simple domain language-like set of macros to describe
13
- the former and integrating the Single Table Inheritance pattern for the latter, Active Record narrows the
14
- gap of functionality between the data mapper and active record approach.
15
-
16
- A short rundown of the major features:
17
-
18
- * Automated mapping between classes and tables, attributes and columns.
19
-
20
- class Product < ActiveRecord::Base; end
21
-
22
- ...is automatically mapped to the table named "products", such as:
23
-
24
- CREATE TABLE products (
25
- id int(11) NOT NULL auto_increment,
26
- name varchar(255),
27
- PRIMARY KEY (id)
28
- );
29
-
30
- ...which again gives Product#name and Product#name=(new_name)
31
-
32
- {Learn more}[link:classes/ActiveRecord/Base.html]
33
-
34
-
35
- * Associations between objects controlled by simple meta-programming macros.
36
-
37
- class Firm < ActiveRecord::Base
38
- has_many :clients
39
- has_one :account
40
- belongs_to :conglomorate
41
- end
42
-
43
- {Learn more}[link:classes/ActiveRecord/Associations/ClassMethods.html]
44
-
45
-
46
- * Aggregations of value objects controlled by simple meta-programming macros.
47
-
48
- class Account < ActiveRecord::Base
49
- composed_of :balance, :class_name => "Money",
50
- :mapping => %w(balance amount)
51
- composed_of :address,
52
- :mapping => [%w(address_street street), %w(address_city city)]
53
- end
54
-
55
- {Learn more}[link:classes/ActiveRecord/Aggregations/ClassMethods.html]
56
-
57
-
58
- * Validation rules that can differ for new or existing objects.
59
-
60
- class Account < ActiveRecord::Base
61
- validates_presence_of :subdomain, :name, :email_address, :password
62
- validates_uniqueness_of :subdomain
63
- validates_acceptance_of :terms_of_service, :on => :create
64
- validates_confirmation_of :password, :email_address, :on => :create
65
- end
66
-
67
- {Learn more}[link:classes/ActiveRecord/Validations.html]
68
-
69
- * Callbacks as methods or queues on the entire lifecycle (instantiation, saving, destroying, validating, etc).
70
-
71
- class Person < ActiveRecord::Base
72
- def before_destroy # is called just before Person#destroy
73
- CreditCard.find(credit_card_id).destroy
74
- end
75
- end
76
-
77
- class Account < ActiveRecord::Base
78
- after_find :eager_load, 'self.class.announce(#{id})'
79
- end
80
-
81
- {Learn more}[link:classes/ActiveRecord/Callbacks.html]
82
-
83
-
84
- * Observers for the entire lifecycle
85
-
86
- class CommentObserver < ActiveRecord::Observer
87
- def after_create(comment) # is called just after Comment#save
88
- Notifications.deliver_new_comment("david@loudthinking.com", comment)
89
- end
90
- end
91
-
92
- {Learn more}[link:classes/ActiveRecord/Observer.html]
93
-
94
-
95
- * Inheritance hierarchies
96
-
97
- class Company < ActiveRecord::Base; end
98
- class Firm < Company; end
99
- class Client < Company; end
100
- class PriorityClient < Client; end
101
-
102
- {Learn more}[link:classes/ActiveRecord/Base.html]
103
-
104
-
105
- * Transactions
106
-
107
- # Database transaction
108
- Account.transaction do
109
- david.withdrawal(100)
110
- mary.deposit(100)
111
- end
112
-
113
- {Learn more}[link:classes/ActiveRecord/Transactions/ClassMethods.html]
114
-
115
-
116
- * Reflections on columns, associations, and aggregations
117
-
118
- reflection = Firm.reflect_on_association(:clients)
119
- reflection.klass # => Client (class)
120
- Firm.columns # Returns an array of column descriptors for the firms table
121
-
122
- {Learn more}[link:classes/ActiveRecord/Reflection/ClassMethods.html]
123
-
124
-
125
- * Direct manipulation (instead of service invocation)
126
-
127
- So instead of (Hibernate[http://www.hibernate.org/] example):
128
-
129
- long pkId = 1234;
130
- DomesticCat pk = (DomesticCat) sess.load( Cat.class, new Long(pkId) );
131
- // something interesting involving a cat...
132
- sess.save(cat);
133
- sess.flush(); // force the SQL INSERT
134
-
135
- Active Record lets you:
136
-
137
- pkId = 1234
138
- cat = Cat.find(pkId)
139
- # something even more interesting involving the same cat...
140
- cat.save
141
-
142
- {Learn more}[link:classes/ActiveRecord/Base.html]
143
-
144
-
145
- * Database abstraction through simple adapters (~100 lines) with a shared connector
146
-
147
- ActiveRecord::Base.establish_connection(:adapter => "sqlite", :database => "dbfile")
148
-
149
- ActiveRecord::Base.establish_connection(
150
- :adapter => "mysql",
151
- :host => "localhost",
152
- :username => "me",
153
- :password => "secret",
154
- :database => "activerecord"
155
- )
156
-
157
- {Learn more}[link:classes/ActiveRecord/Base.html#M000081] and read about the built-in support for
158
- MySQL[link:classes/ActiveRecord/ConnectionAdapters/MysqlAdapter.html], PostgreSQL[link:classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html], SQLite[link:classes/ActiveRecord/ConnectionAdapters/SQLiteAdapter.html], Oracle[link:classes/ActiveRecord/ConnectionAdapters/OracleAdapter.html], SQLServer[link:classes/ActiveRecord/ConnectionAdapters/SQLServerAdapter.html], and DB2[link:classes/ActiveRecord/ConnectionAdapters/DB2Adapter.html].
159
-
160
-
161
- * Logging support for Log4r[http://log4r.sourceforge.net] and Logger[http://www.ruby-doc.org/stdlib/libdoc/logger/rdoc]
162
-
163
- ActiveRecord::Base.logger = Logger.new(STDOUT)
164
- ActiveRecord::Base.logger = Log4r::Logger.new("Application Log")
165
-
166
-
167
- * Database agnostic schema management with Migrations
168
-
169
- class AddSystemSettings < ActiveRecord::Migration
170
- def self.up
171
- create_table :system_settings do |t|
172
- t.string :name
173
- t.string :label
174
- t.text :value
175
- t.string :type
176
- t.integer :position
177
- end
178
-
179
- SystemSetting.create :name => "notice", :label => "Use notice?", :value => 1
180
- end
181
-
182
- def self.down
183
- drop_table :system_settings
184
- end
185
- end
186
-
187
- {Learn more}[link:classes/ActiveRecord/Migration.html]
188
-
189
- == Simple example (1/2): Defining tables and classes (using MySQL)
190
-
191
- Data definitions are specified only in the database. Active Record queries the database for
192
- the column names (that then serves to determine which attributes are valid) on regular
193
- object instantiation through the new constructor and relies on the column names in the rows
194
- with the finders.
195
-
196
- # CREATE TABLE companies (
197
- # id int(11) unsigned NOT NULL auto_increment,
198
- # client_of int(11),
199
- # name varchar(255),
200
- # type varchar(100),
201
- # PRIMARY KEY (id)
202
- # )
203
-
204
- Active Record automatically links the "Company" object to the "companies" table
205
-
206
- class Company < ActiveRecord::Base
207
- has_many :people, :class_name => "Person"
208
- end
209
-
210
- class Firm < Company
211
- has_many :clients
212
-
213
- def people_with_all_clients
214
- clients.inject([]) { |people, client| people + client.people }
215
- end
216
- end
217
-
218
- The foreign_key is only necessary because we didn't use "firm_id" in the data definition
219
-
220
- class Client < Company
221
- belongs_to :firm, :foreign_key => "client_of"
222
- end
223
-
224
- # CREATE TABLE people (
225
- # id int(11) unsigned NOT NULL auto_increment,
226
- # name text,
227
- # company_id text,
228
- # PRIMARY KEY (id)
229
- # )
230
-
231
- Active Record will also automatically link the "Person" object to the "people" table
232
-
233
- class Person < ActiveRecord::Base
234
- belongs_to :company
235
- end
236
-
237
- == Simple example (2/2): Using the domain
238
-
239
- Picking a database connection for all the Active Records
240
-
241
- ActiveRecord::Base.establish_connection(
242
- :adapter => "mysql",
243
- :host => "localhost",
244
- :username => "me",
245
- :password => "secret",
246
- :database => "activerecord"
247
- )
248
-
249
- Create some fixtures
250
-
251
- firm = Firm.new("name" => "Next Angle")
252
- # SQL: INSERT INTO companies (name, type) VALUES("Next Angle", "Firm")
253
- firm.save
254
-
255
- client = Client.new("name" => "37signals", "client_of" => firm.id)
256
- # SQL: INSERT INTO companies (name, client_of, type) VALUES("37signals", 1, "Firm")
257
- client.save
258
-
259
- Lots of different finders
260
-
261
- # SQL: SELECT * FROM companies WHERE id = 1
262
- next_angle = Company.find(1)
263
-
264
- # SQL: SELECT * FROM companies WHERE id = 1 AND type = 'Firm'
265
- next_angle = Firm.find(1)
266
-
267
- # SQL: SELECT * FROM companies WHERE id = 1 AND name = 'Next Angle'
268
- next_angle = Company.find(:first, :conditions => "name = 'Next Angle'")
269
-
270
- next_angle = Firm.find_by_sql("SELECT * FROM companies WHERE id = 1").first
271
-
272
- The supertype, Company, will return subtype instances
273
-
274
- Firm === next_angle
275
-
276
- All the dynamic methods added by the has_many macro
277
-
278
- next_angle.clients.empty? # true
279
- next_angle.clients.size # total number of clients
280
- all_clients = next_angle.clients
281
-
282
- Constrained finds makes access security easier when ID comes from a web-app
283
-
284
- # SQL: SELECT * FROM companies WHERE client_of = 1 AND type = 'Client' AND id = 2
285
- thirty_seven_signals = next_angle.clients.find(2)
286
-
287
- Bi-directional associations thanks to the "belongs_to" macro
288
-
289
- thirty_seven_signals.firm.nil? # true
290
-
291
-
292
- == Philosophy
293
-
294
- Active Record attempts to provide a coherent wrapper as a solution for the inconvenience that is
295
- object-relational mapping. The prime directive for this mapping has been to minimize
296
- the amount of code needed to build a real-world domain model. This is made possible
297
- by relying on a number of conventions that make it easy for Active Record to infer
298
- complex relations and structures from a minimal amount of explicit direction.
299
-
300
- Convention over Configuration:
301
- * No XML-files!
302
- * Lots of reflection and run-time extension
303
- * Magic is not inherently a bad word
304
-
305
- Admit the Database:
306
- * Lets you drop down to SQL for odd cases and performance
307
- * Doesn't attempt to duplicate or replace data definitions
308
-
309
-
310
- == Download
311
-
312
- The latest version of Active Record can be found at
313
-
314
- * http://rubyforge.org/project/showfiles.php?group_id=182
315
-
316
- Documentation can be found at
317
-
318
- * http://ar.rubyonrails.com
319
-
320
-
321
- == Installation
322
-
323
- The prefered method of installing Active Record is through its GEM file. You'll need to have
324
- RubyGems[http://rubygems.rubyforge.org/wiki/wiki.pl] installed for that, though. If you have,
325
- then use:
326
-
327
- % [sudo] gem install activerecord-1.10.0.gem
328
-
329
- You can also install Active Record the old-fashioned way with the following command:
330
-
331
- % [sudo] ruby install.rb
332
-
333
- from its distribution directory.
334
-
335
-
336
- == License
337
-
338
- Active Record is released under the MIT license.
339
-
340
-
341
- == Support
342
-
343
- The Active Record homepage is http://www.rubyonrails.com. You can find the Active Record
344
- RubyForge page at http://rubyforge.org/projects/activerecord. And as Jim from Rake says:
345
-
346
- Feel free to submit commits or feature requests. If you send a patch,
347
- remember to update the corresponding unit tests. If fact, I prefer
348
- new feature to be submitted in the form of new unit tests.
349
-
350
- For other information, feel free to ask on the rubyonrails-talk
351
- (http://groups.google.com/group/rubyonrails-talk) mailing list.