activerecord 3.0.0.beta → 3.0.0.beta2
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.
- data/CHANGELOG +8 -1
- data/lib/active_record.rb +9 -6
- data/lib/active_record/aggregations.rb +5 -0
- data/lib/active_record/association_preload.rb +7 -2
- data/lib/active_record/associations.rb +74 -54
- data/lib/active_record/associations/association_collection.rb +1 -0
- data/lib/active_record/associations/association_proxy.rb +2 -1
- data/lib/active_record/associations/has_many_association.rb +4 -0
- data/lib/active_record/associations/has_many_through_association.rb +1 -0
- data/lib/active_record/attribute_methods/dirty.rb +11 -9
- data/lib/active_record/attribute_methods/primary_key.rb +6 -0
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/base.rb +57 -212
- data/lib/active_record/callbacks.rb +10 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +24 -1
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +10 -5
- data/lib/active_record/connection_adapters/abstract_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +22 -5
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +34 -8
- data/lib/active_record/dynamic_finder_match.rb +3 -0
- data/lib/active_record/errors.rb +165 -0
- data/lib/active_record/fixtures.rb +1 -0
- data/lib/active_record/migration.rb +8 -6
- data/lib/active_record/named_scope.rb +14 -5
- data/lib/active_record/nested_attributes.rb +6 -2
- data/lib/active_record/query_cache.rb +2 -0
- data/lib/active_record/railtie.rb +30 -19
- data/lib/active_record/railties/databases.rake +13 -7
- data/lib/active_record/railties/{subscriber.rb → log_subscriber.rb} +7 -2
- data/lib/active_record/reflection.rb +5 -3
- data/lib/active_record/relation.rb +13 -2
- data/lib/active_record/relation/batches.rb +84 -0
- data/lib/active_record/relation/calculations.rb +2 -0
- data/lib/active_record/relation/finder_methods.rb +13 -2
- data/lib/active_record/relation/predicate_builder.rb +2 -7
- data/lib/active_record/relation/query_methods.rb +20 -27
- data/lib/active_record/relation/spawn_methods.rb +18 -28
- data/lib/active_record/schema.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +2 -4
- data/lib/active_record/version.rb +3 -2
- data/lib/{generators → rails/generators}/active_record.rb +0 -0
- data/lib/{generators → rails/generators}/active_record/migration/migration_generator.rb +1 -1
- data/lib/{generators → rails/generators}/active_record/migration/templates/migration.rb +0 -0
- data/lib/{generators → rails/generators}/active_record/model/model_generator.rb +1 -1
- data/lib/{generators → rails/generators}/active_record/model/templates/migration.rb +0 -0
- data/lib/{generators → rails/generators}/active_record/model/templates/model.rb +0 -0
- data/lib/{generators → rails/generators}/active_record/observer/observer_generator.rb +1 -1
- data/lib/{generators → rails/generators}/active_record/observer/templates/observer.rb +0 -0
- data/lib/{generators → rails/generators}/active_record/session_migration/session_migration_generator.rb +1 -1
- data/lib/{generators → rails/generators}/active_record/session_migration/templates/migration.rb +0 -0
- metadata +61 -34
- data/lib/active_record/batches.rb +0 -79
@@ -205,6 +205,16 @@ module ActiveRecord
|
|
205
205
|
# including <tt>after_*</tt> hooks. Note, however, that in that case the client
|
206
206
|
# needs to be aware of it because an ordinary +save+ will raise such exception
|
207
207
|
# instead of quietly returning +false+.
|
208
|
+
#
|
209
|
+
# == Debugging callbacks
|
210
|
+
#
|
211
|
+
# To list the methods and procs registered with a particular callback, append <tt>_callback_chain</tt> to the callback name that you wish to list and send that to your class from the Rails console:
|
212
|
+
#
|
213
|
+
# >> Topic.after_save_callback_chain
|
214
|
+
# => [#<ActiveSupport::Callbacks::Callback:0x3f6a448
|
215
|
+
# @method=#<Proc:0x03f9a42c@/Users/foo/bar/app/models/topic.rb:43>, kind:after_save, identifiernil,
|
216
|
+
# options{}]
|
217
|
+
#
|
208
218
|
module Callbacks
|
209
219
|
extend ActiveSupport::Concern
|
210
220
|
|
@@ -113,7 +113,7 @@ module ActiveRecord
|
|
113
113
|
def transaction(options = {})
|
114
114
|
options.assert_valid_keys :requires_new, :joinable
|
115
115
|
|
116
|
-
last_transaction_joinable = @transaction_joinable
|
116
|
+
last_transaction_joinable = defined?(@transaction_joinable) ? @transaction_joinable : nil
|
117
117
|
if options.has_key?(:joinable)
|
118
118
|
@transaction_joinable = options[:joinable]
|
119
119
|
else
|
@@ -181,6 +181,29 @@ module ActiveRecord
|
|
181
181
|
# done if the transaction block raises an exception or returns false.
|
182
182
|
def rollback_db_transaction() end
|
183
183
|
|
184
|
+
# Appends +LIMIT+ and +OFFSET+ options to an SQL statement, or some SQL
|
185
|
+
# fragment that has the same semantics as LIMIT and OFFSET.
|
186
|
+
#
|
187
|
+
# +options+ must be a Hash which contains a +:limit+ option
|
188
|
+
# and an +:offset+ option.
|
189
|
+
#
|
190
|
+
# This method *modifies* the +sql+ parameter.
|
191
|
+
#
|
192
|
+
# ===== Examples
|
193
|
+
# add_limit_offset!('SELECT * FROM suppliers', {:limit => 10, :offset => 50})
|
194
|
+
# generates
|
195
|
+
# SELECT * FROM suppliers LIMIT 10 OFFSET 50
|
196
|
+
|
197
|
+
def add_limit_offset!(sql, options)
|
198
|
+
if limit = options[:limit]
|
199
|
+
sql << " LIMIT #{sanitize_limit(limit)}"
|
200
|
+
end
|
201
|
+
if offset = options[:offset]
|
202
|
+
sql << " OFFSET #{offset.to_i}"
|
203
|
+
end
|
204
|
+
sql
|
205
|
+
end
|
206
|
+
|
184
207
|
def default_sequence_name(table, column)
|
185
208
|
nil
|
186
209
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/object/blank'
|
1
2
|
require 'date'
|
2
3
|
require 'set'
|
3
4
|
require 'bigdecimal'
|
@@ -22,7 +23,8 @@ module ActiveRecord
|
|
22
23
|
#
|
23
24
|
# +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
|
24
25
|
# +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
|
25
|
-
# +sql_type+ is
|
26
|
+
# +sql_type+ is used to extract the column's length, if necessary. For example +60+ in <tt>company_name varchar(60)</tt>.
|
27
|
+
# It will be mapped to one of the standard Rails SQL types in the <tt>type</tt> attribute.
|
26
28
|
# +null+ determines if this column allows +NULL+ values.
|
27
29
|
def initialize(name, default, sql_type = nil, null = true)
|
28
30
|
@name, @sql_type, @null = name, sql_type, null
|
@@ -319,16 +321,19 @@ module ActiveRecord
|
|
319
321
|
def method_missing(symbol, *args)
|
320
322
|
if symbol.to_s == 'xml'
|
321
323
|
xml_column_fallback(args)
|
324
|
+
else
|
325
|
+
super
|
322
326
|
end
|
323
327
|
end
|
324
328
|
|
325
329
|
def xml_column_fallback(*args)
|
326
330
|
case @base.adapter_name.downcase
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
end
|
331
|
+
when 'sqlite', 'mysql'
|
332
|
+
options = args.extract_options!
|
333
|
+
column(args[0], :text, options)
|
331
334
|
end
|
335
|
+
end
|
336
|
+
|
332
337
|
# Appends a primary key definition to the table definition.
|
333
338
|
# Can be called multiple times, but this is probably not a good idea.
|
334
339
|
def primary_key(name)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_record/connection_adapters/abstract_adapter'
|
2
2
|
require 'active_support/core_ext/kernel/requires'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
3
4
|
require 'set'
|
4
5
|
|
5
6
|
module MysqlCompat #:nodoc:
|
@@ -61,7 +62,7 @@ module ActiveRecord
|
|
61
62
|
begin
|
62
63
|
require_library_or_gem('mysql')
|
63
64
|
rescue LoadError
|
64
|
-
$stderr.puts '!!!
|
65
|
+
$stderr.puts '!!! Please install the mysql gem and try again: gem install mysql.'
|
65
66
|
raise
|
66
67
|
end
|
67
68
|
end
|
@@ -321,7 +322,11 @@ module ActiveRecord
|
|
321
322
|
|
322
323
|
# Executes a SQL query and returns a MySQL::Result object. Note that you have to free the Result object after you're done using it.
|
323
324
|
def execute(sql, name = nil) #:nodoc:
|
324
|
-
|
325
|
+
if name == :skip_logging
|
326
|
+
@connection.query(sql)
|
327
|
+
else
|
328
|
+
log(sql, name) { @connection.query(sql) }
|
329
|
+
end
|
325
330
|
rescue ActiveRecord::StatementInvalid => exception
|
326
331
|
if exception.message.split(":").first =~ /Packets out of order/
|
327
332
|
raise ActiveRecord::StatementInvalid, "'Packets out of order' error was received from the database. Please update your mysql bindings (gem install mysql) and read http://dev.mysql.com/doc/mysql/en/password-hashing.html for more information. If you're on Windows, use the Instant Rails installer to get the updated mysql bindings."
|
@@ -371,6 +376,18 @@ module ActiveRecord
|
|
371
376
|
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
|
372
377
|
end
|
373
378
|
|
379
|
+
def add_limit_offset!(sql, options) #:nodoc:
|
380
|
+
limit, offset = options[:limit], options[:offset]
|
381
|
+
if limit && offset
|
382
|
+
sql << " LIMIT #{offset.to_i}, #{sanitize_limit(limit)}"
|
383
|
+
elsif limit
|
384
|
+
sql << " LIMIT #{sanitize_limit(limit)}"
|
385
|
+
elsif offset
|
386
|
+
sql << " OFFSET #{offset.to_i}"
|
387
|
+
end
|
388
|
+
sql
|
389
|
+
end
|
390
|
+
|
374
391
|
# SCHEMA STATEMENTS ========================================
|
375
392
|
|
376
393
|
def structure_dump #:nodoc:
|
@@ -456,7 +473,7 @@ module ActiveRecord
|
|
456
473
|
def columns(table_name, name = nil)#:nodoc:
|
457
474
|
sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
|
458
475
|
columns = []
|
459
|
-
result = execute(sql,
|
476
|
+
result = execute(sql, :skip_logging)
|
460
477
|
result.each { |field| columns << MysqlColumn.new(field[0], field[4], field[1], field[2] == "YES") }
|
461
478
|
result.free
|
462
479
|
columns
|
@@ -616,11 +633,11 @@ module ActiveRecord
|
|
616
633
|
|
617
634
|
def configure_connection
|
618
635
|
encoding = @config[:encoding]
|
619
|
-
execute("SET NAMES '#{encoding}'") if encoding
|
636
|
+
execute("SET NAMES '#{encoding}'", :skip_logging) if encoding
|
620
637
|
|
621
638
|
# By default, MySQL 'where id is null' selects the last inserted id.
|
622
639
|
# Turn this off. http://dev.rubyonrails.org/ticket/6778
|
623
|
-
execute("SET SQL_AUTO_IS_NULL=0")
|
640
|
+
execute("SET SQL_AUTO_IS_NULL=0", :skip_logging)
|
624
641
|
end
|
625
642
|
|
626
643
|
def select(sql, name = nil)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_record/connection_adapters/abstract_adapter'
|
2
2
|
require 'active_support/core_ext/kernel/requires'
|
3
|
+
require 'active_support/core_ext/object/blank'
|
3
4
|
|
4
5
|
begin
|
5
6
|
require_library_or_gem 'pg'
|
@@ -113,6 +114,12 @@ module ActiveRecord
|
|
113
114
|
# Object identifier types
|
114
115
|
when /^oid$/
|
115
116
|
:integer
|
117
|
+
# UUID type
|
118
|
+
when /^uuid$/
|
119
|
+
:string
|
120
|
+
# Small and big integer types
|
121
|
+
when /^(?:small|big)int$/
|
122
|
+
:integer
|
116
123
|
# Pass through all types that are not specific to PostgreSQL.
|
117
124
|
else
|
118
125
|
super
|
@@ -299,7 +306,7 @@ module ActiveRecord
|
|
299
306
|
# QUOTING ==================================================
|
300
307
|
|
301
308
|
# Escapes binary strings for bytea input to the database.
|
302
|
-
def escape_bytea(
|
309
|
+
def escape_bytea(original_value)
|
303
310
|
if @connection.respond_to?(:escape_bytea)
|
304
311
|
self.class.instance_eval do
|
305
312
|
define_method(:escape_bytea) do |value|
|
@@ -323,13 +330,13 @@ module ActiveRecord
|
|
323
330
|
end
|
324
331
|
end
|
325
332
|
end
|
326
|
-
escape_bytea(
|
333
|
+
escape_bytea(original_value)
|
327
334
|
end
|
328
335
|
|
329
336
|
# Unescapes bytea output from a database to the binary string it represents.
|
330
337
|
# NOTE: This is NOT an inverse of escape_bytea! This is only to be used
|
331
338
|
# on escaped binary output from database drive.
|
332
|
-
def unescape_bytea(
|
339
|
+
def unescape_bytea(original_value)
|
333
340
|
# In each case, check if the value actually is escaped PostgreSQL bytea output
|
334
341
|
# or an unescaped Active Record attribute that was just written.
|
335
342
|
if PGconn.respond_to?(:unescape_bytea)
|
@@ -369,7 +376,7 @@ module ActiveRecord
|
|
369
376
|
end
|
370
377
|
end
|
371
378
|
end
|
372
|
-
unescape_bytea(
|
379
|
+
unescape_bytea(original_value)
|
373
380
|
end
|
374
381
|
|
375
382
|
# Quotes PostgreSQL-specific data types for SQL input.
|
@@ -394,7 +401,7 @@ module ActiveRecord
|
|
394
401
|
end
|
395
402
|
|
396
403
|
# Quotes strings for use in SQL input in the postgres driver for better performance.
|
397
|
-
def quote_string(
|
404
|
+
def quote_string(original_value) #:nodoc:
|
398
405
|
if @connection.respond_to?(:escape)
|
399
406
|
self.class.instance_eval do
|
400
407
|
define_method(:quote_string) do |s|
|
@@ -414,7 +421,7 @@ module ActiveRecord
|
|
414
421
|
remove_method(:quote_string)
|
415
422
|
end
|
416
423
|
end
|
417
|
-
quote_string(
|
424
|
+
quote_string(original_value)
|
418
425
|
end
|
419
426
|
|
420
427
|
# Checks the following cases:
|
@@ -651,14 +658,33 @@ module ActiveRecord
|
|
651
658
|
end
|
652
659
|
end
|
653
660
|
|
661
|
+
# Creates a schema for the given user
|
662
|
+
#
|
663
|
+
# Example:
|
664
|
+
# create_schema('products', 'postgres')
|
665
|
+
def create_schema(schema_name, pg_username)
|
666
|
+
execute("CREATE SCHEMA \"#{schema_name}\" AUTHORIZATION \"#{pg_username}\"")
|
667
|
+
end
|
668
|
+
|
669
|
+
# Drops a schema
|
670
|
+
#
|
671
|
+
# Example:
|
672
|
+
# drop_schema('products')
|
673
|
+
def drop_schema(schema_name)
|
674
|
+
execute("DROP SCHEMA \"#{schema_name}\"")
|
675
|
+
end
|
676
|
+
|
677
|
+
# Returns an array of all schemas in the database
|
678
|
+
def all_schemas
|
679
|
+
query('SELECT schema_name FROM information_schema.schemata').flatten
|
680
|
+
end
|
654
681
|
|
655
682
|
# Returns the list of all tables in the schema search path or a specified schema.
|
656
683
|
def tables(name = nil)
|
657
|
-
schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
|
658
684
|
query(<<-SQL, name).map { |row| row[0] }
|
659
685
|
SELECT tablename
|
660
686
|
FROM pg_tables
|
661
|
-
WHERE schemaname
|
687
|
+
WHERE schemaname = ANY (current_schemas(false))
|
662
688
|
SQL
|
663
689
|
end
|
664
690
|
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
# Generic Active Record exception class.
|
3
|
+
class ActiveRecordError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
# Raised when the single-table inheritance mechanism fails to locate the subclass
|
7
|
+
# (for example due to improper usage of column that +inheritance_column+ points to).
|
8
|
+
class SubclassNotFound < ActiveRecordError #:nodoc:
|
9
|
+
end
|
10
|
+
|
11
|
+
# Raised when an object assigned to an association has an incorrect type.
|
12
|
+
#
|
13
|
+
# class Ticket < ActiveRecord::Base
|
14
|
+
# has_many :patches
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# class Patch < ActiveRecord::Base
|
18
|
+
# belongs_to :ticket
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# # Comments are not patches, this assignment raises AssociationTypeMismatch.
|
22
|
+
# @ticket.patches << Comment.new(:content => "Please attach tests to your patch.")
|
23
|
+
class AssociationTypeMismatch < ActiveRecordError
|
24
|
+
end
|
25
|
+
|
26
|
+
# Raised when unserialized object's type mismatches one specified for serializable field.
|
27
|
+
class SerializationTypeMismatch < ActiveRecordError
|
28
|
+
end
|
29
|
+
|
30
|
+
# Raised when adapter not specified on connection (or configuration file <tt>config/database.yml</tt> misses adapter field).
|
31
|
+
class AdapterNotSpecified < ActiveRecordError
|
32
|
+
end
|
33
|
+
|
34
|
+
# Raised when Active Record cannot find database adapter specified in <tt>config/database.yml</tt> or programmatically.
|
35
|
+
class AdapterNotFound < ActiveRecordError
|
36
|
+
end
|
37
|
+
|
38
|
+
# Raised when connection to the database could not been established (for example when <tt>connection=</tt> is given a nil object).
|
39
|
+
class ConnectionNotEstablished < ActiveRecordError
|
40
|
+
end
|
41
|
+
|
42
|
+
# Raised when Active Record cannot find record by given id or set of ids.
|
43
|
+
class RecordNotFound < ActiveRecordError
|
44
|
+
end
|
45
|
+
|
46
|
+
# Raised by ActiveRecord::Base.save! and ActiveRecord::Base.create! methods when record cannot be
|
47
|
+
# saved because record is invalid.
|
48
|
+
class RecordNotSaved < ActiveRecordError
|
49
|
+
end
|
50
|
+
|
51
|
+
# Raised when SQL statement cannot be executed by the database (for example, it's often the case for MySQL when Ruby driver used is too old).
|
52
|
+
class StatementInvalid < ActiveRecordError
|
53
|
+
end
|
54
|
+
|
55
|
+
# Raised when SQL statement is invalid and the application gets a blank result.
|
56
|
+
class ThrowResult < ActiveRecordError
|
57
|
+
end
|
58
|
+
|
59
|
+
# Parent class for all specific exceptions which wrap database driver exceptions
|
60
|
+
# provides access to the original exception also.
|
61
|
+
class WrappedDatabaseException < StatementInvalid
|
62
|
+
attr_reader :original_exception
|
63
|
+
|
64
|
+
def initialize(message, original_exception)
|
65
|
+
super(message)
|
66
|
+
@original_exception = original_exception
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Raised when a record cannot be inserted because it would violate a uniqueness constraint.
|
71
|
+
class RecordNotUnique < WrappedDatabaseException
|
72
|
+
end
|
73
|
+
|
74
|
+
# Raised when a record cannot be inserted or updated because it references a non-existent record.
|
75
|
+
class InvalidForeignKey < WrappedDatabaseException
|
76
|
+
end
|
77
|
+
|
78
|
+
# Raised when number of bind variables in statement given to <tt>:condition</tt> key (for example, when using +find+ method)
|
79
|
+
# does not match number of expected variables.
|
80
|
+
#
|
81
|
+
# For example, in
|
82
|
+
#
|
83
|
+
# Location.find :all, :conditions => ["lat = ? AND lng = ?", 53.7362]
|
84
|
+
#
|
85
|
+
# two placeholders are given but only one variable to fill them.
|
86
|
+
class PreparedStatementInvalid < ActiveRecordError
|
87
|
+
end
|
88
|
+
|
89
|
+
# Raised on attempt to save stale record. Record is stale when it's being saved in another query after
|
90
|
+
# instantiation, for example, when two users edit the same wiki page and one starts editing and saves
|
91
|
+
# the page before the other.
|
92
|
+
#
|
93
|
+
# Read more about optimistic locking in ActiveRecord::Locking module RDoc.
|
94
|
+
class StaleObjectError < ActiveRecordError
|
95
|
+
end
|
96
|
+
|
97
|
+
# Raised when association is being configured improperly or
|
98
|
+
# user tries to use offset and limit together with has_many or has_and_belongs_to_many associations.
|
99
|
+
class ConfigurationError < ActiveRecordError
|
100
|
+
end
|
101
|
+
|
102
|
+
# Raised on attempt to update record that is instantiated as read only.
|
103
|
+
class ReadOnlyRecord < ActiveRecordError
|
104
|
+
end
|
105
|
+
|
106
|
+
# ActiveRecord::Transactions::ClassMethods.transaction uses this exception
|
107
|
+
# to distinguish a deliberate rollback from other exceptional situations.
|
108
|
+
# Normally, raising an exception will cause the +transaction+ method to rollback
|
109
|
+
# the database transaction *and* pass on the exception. But if you raise an
|
110
|
+
# ActiveRecord::Rollback exception, then the database transaction will be rolled back,
|
111
|
+
# without passing on the exception.
|
112
|
+
#
|
113
|
+
# For example, you could do this in your controller to rollback a transaction:
|
114
|
+
#
|
115
|
+
# class BooksController < ActionController::Base
|
116
|
+
# def create
|
117
|
+
# Book.transaction do
|
118
|
+
# book = Book.new(params[:book])
|
119
|
+
# book.save!
|
120
|
+
# if today_is_friday?
|
121
|
+
# # The system must fail on Friday so that our support department
|
122
|
+
# # won't be out of job. We silently rollback this transaction
|
123
|
+
# # without telling the user.
|
124
|
+
# raise ActiveRecord::Rollback, "Call tech support!"
|
125
|
+
# end
|
126
|
+
# end
|
127
|
+
# # ActiveRecord::Rollback is the only exception that won't be passed on
|
128
|
+
# # by ActiveRecord::Base.transaction, so this line will still be reached
|
129
|
+
# # even on Friday.
|
130
|
+
# redirect_to root_url
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
class Rollback < ActiveRecordError
|
134
|
+
end
|
135
|
+
|
136
|
+
# Raised when attribute has a name reserved by Active Record (when attribute has name of one of Active Record instance methods).
|
137
|
+
class DangerousAttributeError < ActiveRecordError
|
138
|
+
end
|
139
|
+
|
140
|
+
# Raised when unknown attributes are supplied via mass assignment.
|
141
|
+
class UnknownAttributeError < NoMethodError
|
142
|
+
end
|
143
|
+
|
144
|
+
# Raised when an error occurred while doing a mass assignment to an attribute through the
|
145
|
+
# <tt>attributes=</tt> method. The exception has an +attribute+ property that is the name of the
|
146
|
+
# offending attribute.
|
147
|
+
class AttributeAssignmentError < ActiveRecordError
|
148
|
+
attr_reader :exception, :attribute
|
149
|
+
def initialize(message, exception, attribute)
|
150
|
+
@exception = exception
|
151
|
+
@attribute = attribute
|
152
|
+
@message = message
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Raised when there are multiple errors while doing a mass assignment through the +attributes+
|
157
|
+
# method. The exception has an +errors+ property that contains an array of AttributeAssignmentError
|
158
|
+
# objects, each corresponding to the error while assigning to an attribute.
|
159
|
+
class MultiparameterAssignmentErrors < ActiveRecordError
|
160
|
+
attr_reader :errors
|
161
|
+
def initialize(errors)
|
162
|
+
@errors = errors
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|