activerecord 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- data/CHANGELOG +4928 -3
 - data/README +45 -46
 - data/RUNNING_UNIT_TESTS +8 -11
 - data/Rakefile +247 -0
 - data/install.rb +8 -38
 - data/lib/active_record/aggregations.rb +64 -49
 - data/lib/active_record/associations/association_collection.rb +217 -47
 - data/lib/active_record/associations/association_proxy.rb +159 -0
 - data/lib/active_record/associations/belongs_to_association.rb +56 -0
 - data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
 - data/lib/active_record/associations/has_and_belongs_to_many_association.rb +155 -37
 - data/lib/active_record/associations/has_many_association.rb +145 -75
 - data/lib/active_record/associations/has_many_through_association.rb +283 -0
 - data/lib/active_record/associations/has_one_association.rb +96 -0
 - data/lib/active_record/associations.rb +1537 -304
 - data/lib/active_record/attribute_methods.rb +328 -0
 - data/lib/active_record/base.rb +2001 -588
 - data/lib/active_record/calculations.rb +269 -0
 - data/lib/active_record/callbacks.rb +169 -165
 - data/lib/active_record/connection_adapters/abstract/connection_specification.rb +308 -0
 - data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -0
 - data/lib/active_record/connection_adapters/abstract/query_cache.rb +87 -0
 - data/lib/active_record/connection_adapters/abstract/quoting.rb +69 -0
 - data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +472 -0
 - data/lib/active_record/connection_adapters/abstract/schema_statements.rb +306 -0
 - data/lib/active_record/connection_adapters/abstract_adapter.rb +125 -279
 - data/lib/active_record/connection_adapters/mysql_adapter.rb +442 -77
 - data/lib/active_record/connection_adapters/postgresql_adapter.rb +805 -135
 - data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
 - data/lib/active_record/connection_adapters/sqlite_adapter.rb +353 -69
 - data/lib/active_record/fixtures.rb +946 -100
 - data/lib/active_record/locking/optimistic.rb +144 -0
 - data/lib/active_record/locking/pessimistic.rb +77 -0
 - data/lib/active_record/migration.rb +417 -0
 - data/lib/active_record/observer.rb +142 -32
 - data/lib/active_record/query_cache.rb +23 -0
 - data/lib/active_record/reflection.rb +163 -70
 - data/lib/active_record/schema.rb +58 -0
 - data/lib/active_record/schema_dumper.rb +171 -0
 - data/lib/active_record/serialization.rb +98 -0
 - data/lib/active_record/serializers/json_serializer.rb +71 -0
 - data/lib/active_record/serializers/xml_serializer.rb +315 -0
 - data/lib/active_record/timestamp.rb +41 -0
 - data/lib/active_record/transactions.rb +87 -57
 - data/lib/active_record/validations.rb +909 -122
 - data/lib/active_record/vendor/db2.rb +362 -0
 - data/lib/active_record/vendor/mysql.rb +126 -29
 - data/lib/active_record/version.rb +9 -0
 - data/lib/active_record.rb +35 -7
 - data/lib/activerecord.rb +1 -0
 - data/test/aaa_create_tables_test.rb +72 -0
 - data/test/abstract_unit.rb +73 -5
 - data/test/active_schema_test_mysql.rb +43 -0
 - data/test/adapter_test.rb +105 -0
 - data/test/adapter_test_sqlserver.rb +95 -0
 - data/test/aggregations_test.rb +110 -16
 - data/test/all.sh +2 -2
 - data/test/ar_schema_test.rb +33 -0
 - data/test/association_inheritance_reload.rb +14 -0
 - data/test/associations/ar_joins_test.rb +0 -0
 - data/test/associations/callbacks_test.rb +147 -0
 - data/test/associations/cascaded_eager_loading_test.rb +110 -0
 - data/test/associations/eager_singularization_test.rb +145 -0
 - data/test/associations/eager_test.rb +442 -0
 - data/test/associations/extension_test.rb +47 -0
 - data/test/associations/inner_join_association_test.rb +88 -0
 - data/test/associations/join_model_test.rb +553 -0
 - data/test/associations_test.rb +1930 -267
 - data/test/attribute_methods_test.rb +146 -0
 - data/test/base_test.rb +1316 -84
 - data/test/binary_test.rb +32 -0
 - data/test/calculations_test.rb +251 -0
 - data/test/callbacks_test.rb +400 -0
 - data/test/class_inheritable_attributes_test.rb +3 -4
 - data/test/column_alias_test.rb +17 -0
 - data/test/connection_test_firebird.rb +8 -0
 - data/test/connection_test_mysql.rb +30 -0
 - data/test/connections/native_db2/connection.rb +25 -0
 - data/test/connections/native_firebird/connection.rb +26 -0
 - data/test/connections/native_frontbase/connection.rb +27 -0
 - data/test/connections/native_mysql/connection.rb +21 -18
 - data/test/connections/native_openbase/connection.rb +21 -0
 - data/test/connections/native_oracle/connection.rb +27 -0
 - data/test/connections/native_postgresql/connection.rb +17 -18
 - data/test/connections/native_sqlite/connection.rb +17 -16
 - data/test/connections/native_sqlite3/connection.rb +25 -0
 - data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
 - data/test/connections/native_sybase/connection.rb +23 -0
 - data/test/copy_table_test_sqlite.rb +69 -0
 - data/test/datatype_test_postgresql.rb +203 -0
 - data/test/date_time_test.rb +37 -0
 - data/test/default_test_firebird.rb +16 -0
 - data/test/defaults_test.rb +67 -0
 - data/test/deprecated_finder_test.rb +30 -0
 - data/test/finder_test.rb +607 -32
 - data/test/fixtures/accounts.yml +28 -0
 - data/test/fixtures/all/developers.yml +0 -0
 - data/test/fixtures/all/people.csv +0 -0
 - data/test/fixtures/all/tasks.yml +0 -0
 - data/test/fixtures/author.rb +107 -0
 - data/test/fixtures/author_favorites.yml +4 -0
 - data/test/fixtures/authors.yml +7 -0
 - data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +1 -0
 - data/test/fixtures/bad_fixtures/attr_with_spaces +1 -0
 - data/test/fixtures/bad_fixtures/blank_line +3 -0
 - data/test/fixtures/bad_fixtures/duplicate_attributes +3 -0
 - data/test/fixtures/bad_fixtures/missing_value +1 -0
 - data/test/fixtures/binaries.yml +132 -0
 - data/test/fixtures/binary.rb +2 -0
 - data/test/fixtures/book.rb +4 -0
 - data/test/fixtures/books.yml +7 -0
 - data/test/fixtures/categories/special_categories.yml +9 -0
 - data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
 - data/test/fixtures/categories.yml +14 -0
 - data/test/fixtures/categories_ordered.yml +7 -0
 - data/test/fixtures/categories_posts.yml +23 -0
 - data/test/fixtures/categorization.rb +5 -0
 - data/test/fixtures/categorizations.yml +17 -0
 - data/test/fixtures/category.rb +26 -0
 - data/test/fixtures/citation.rb +6 -0
 - data/test/fixtures/comment.rb +23 -0
 - data/test/fixtures/comments.yml +59 -0
 - data/test/fixtures/companies.yml +55 -0
 - data/test/fixtures/company.rb +81 -4
 - data/test/fixtures/company_in_module.rb +32 -6
 - data/test/fixtures/computer.rb +4 -0
 - data/test/fixtures/computers.yml +4 -0
 - data/test/fixtures/contact.rb +16 -0
 - data/test/fixtures/courses.yml +7 -0
 - data/test/fixtures/customer.rb +28 -3
 - data/test/fixtures/customers.yml +17 -0
 - data/test/fixtures/db_definitions/db2.drop.sql +33 -0
 - data/test/fixtures/db_definitions/db2.sql +235 -0
 - data/test/fixtures/db_definitions/db22.drop.sql +2 -0
 - data/test/fixtures/db_definitions/db22.sql +5 -0
 - data/test/fixtures/db_definitions/firebird.drop.sql +65 -0
 - data/test/fixtures/db_definitions/firebird.sql +310 -0
 - data/test/fixtures/db_definitions/firebird2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/firebird2.sql +6 -0
 - data/test/fixtures/db_definitions/frontbase.drop.sql +33 -0
 - data/test/fixtures/db_definitions/frontbase.sql +273 -0
 - data/test/fixtures/db_definitions/frontbase2.drop.sql +1 -0
 - data/test/fixtures/db_definitions/frontbase2.sql +4 -0
 - data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
 - data/test/fixtures/db_definitions/openbase.sql +318 -0
 - data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/openbase2.sql +7 -0
 - data/test/fixtures/db_definitions/oracle.drop.sql +67 -0
 - data/test/fixtures/db_definitions/oracle.sql +330 -0
 - data/test/fixtures/db_definitions/oracle2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/oracle2.sql +6 -0
 - data/test/fixtures/db_definitions/postgresql.drop.sql +44 -0
 - data/test/fixtures/db_definitions/postgresql.sql +217 -38
 - data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/postgresql2.sql +2 -2
 - data/test/fixtures/db_definitions/schema.rb +354 -0
 - data/test/fixtures/db_definitions/schema2.rb +11 -0
 - data/test/fixtures/db_definitions/sqlite.drop.sql +33 -0
 - data/test/fixtures/db_definitions/sqlite.sql +139 -5
 - data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
 - data/test/fixtures/db_definitions/sqlite2.sql +1 -0
 - data/test/fixtures/db_definitions/sybase.drop.sql +35 -0
 - data/test/fixtures/db_definitions/sybase.sql +222 -0
 - data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
 - data/test/fixtures/db_definitions/sybase2.sql +5 -0
 - data/test/fixtures/developer.rb +70 -6
 - data/test/fixtures/developers.yml +21 -0
 - data/test/fixtures/developers_projects/david_action_controller +2 -1
 - data/test/fixtures/developers_projects/david_active_record +2 -1
 - data/test/fixtures/developers_projects.yml +17 -0
 - data/test/fixtures/edge.rb +5 -0
 - data/test/fixtures/edges.yml +6 -0
 - data/test/fixtures/entrants.yml +14 -0
 - data/test/fixtures/example.log +1 -0
 - data/test/fixtures/fk_test_has_fk.yml +3 -0
 - data/test/fixtures/fk_test_has_pk.yml +2 -0
 - data/test/fixtures/flowers.jpg +0 -0
 - data/test/fixtures/funny_jokes.yml +10 -0
 - data/test/fixtures/item.rb +7 -0
 - data/test/fixtures/items.yml +4 -0
 - data/test/fixtures/joke.rb +3 -0
 - data/test/fixtures/keyboard.rb +3 -0
 - data/test/fixtures/legacy_thing.rb +3 -0
 - data/test/fixtures/legacy_things.yml +3 -0
 - data/test/fixtures/matey.rb +4 -0
 - data/test/fixtures/mateys.yml +4 -0
 - data/test/fixtures/migrations/1_people_have_last_names.rb +9 -0
 - data/test/fixtures/migrations/2_we_need_reminders.rb +12 -0
 - data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
 - data/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb +15 -0
 - data/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb +9 -0
 - data/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb +12 -0
 - data/test/fixtures/migrations_with_duplicate/3_foo.rb +7 -0
 - data/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb +12 -0
 - data/test/fixtures/migrations_with_missing_versions/1000_people_have_middle_names.rb +9 -0
 - data/test/fixtures/migrations_with_missing_versions/1_people_have_last_names.rb +9 -0
 - data/test/fixtures/migrations_with_missing_versions/3_we_need_reminders.rb +12 -0
 - data/test/fixtures/migrations_with_missing_versions/4_innocent_jointable.rb +12 -0
 - data/test/fixtures/minimalistic.rb +2 -0
 - data/test/fixtures/minimalistics.yml +2 -0
 - data/test/fixtures/mixed_case_monkey.rb +3 -0
 - data/test/fixtures/mixed_case_monkeys.yml +6 -0
 - data/test/fixtures/mixins.yml +29 -0
 - data/test/fixtures/movies.yml +7 -0
 - data/test/fixtures/naked/csv/accounts.csv +1 -0
 - data/test/fixtures/naked/yml/accounts.yml +1 -0
 - data/test/fixtures/naked/yml/companies.yml +1 -0
 - data/test/fixtures/naked/yml/courses.yml +1 -0
 - data/test/fixtures/order.rb +4 -0
 - data/test/fixtures/parrot.rb +13 -0
 - data/test/fixtures/parrots.yml +27 -0
 - data/test/fixtures/parrots_pirates.yml +7 -0
 - data/test/fixtures/people.yml +3 -0
 - data/test/fixtures/person.rb +4 -0
 - data/test/fixtures/pirate.rb +5 -0
 - data/test/fixtures/pirates.yml +9 -0
 - data/test/fixtures/post.rb +59 -0
 - data/test/fixtures/posts.yml +48 -0
 - data/test/fixtures/project.rb +27 -2
 - data/test/fixtures/projects.yml +7 -0
 - data/test/fixtures/reader.rb +4 -0
 - data/test/fixtures/readers.yml +4 -0
 - data/test/fixtures/reply.rb +18 -2
 - data/test/fixtures/reserved_words/distinct.yml +5 -0
 - data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
 - data/test/fixtures/reserved_words/group.yml +14 -0
 - data/test/fixtures/reserved_words/select.yml +8 -0
 - data/test/fixtures/reserved_words/values.yml +7 -0
 - data/test/fixtures/ship.rb +3 -0
 - data/test/fixtures/ships.yml +5 -0
 - data/test/fixtures/subject.rb +4 -0
 - data/test/fixtures/subscriber.rb +4 -3
 - data/test/fixtures/tag.rb +7 -0
 - data/test/fixtures/tagging.rb +10 -0
 - data/test/fixtures/taggings.yml +25 -0
 - data/test/fixtures/tags.yml +7 -0
 - data/test/fixtures/task.rb +3 -0
 - data/test/fixtures/tasks.yml +7 -0
 - data/test/fixtures/topic.rb +20 -3
 - data/test/fixtures/topics.yml +22 -0
 - data/test/fixtures/treasure.rb +4 -0
 - data/test/fixtures/treasures.yml +10 -0
 - data/test/fixtures/vertex.rb +9 -0
 - data/test/fixtures/vertices.yml +4 -0
 - data/test/fixtures_test.rb +574 -8
 - data/test/inheritance_test.rb +113 -27
 - data/test/json_serialization_test.rb +180 -0
 - data/test/lifecycle_test.rb +56 -29
 - data/test/locking_test.rb +273 -0
 - data/test/method_scoping_test.rb +416 -0
 - data/test/migration_test.rb +933 -0
 - data/test/migration_test_firebird.rb +124 -0
 - data/test/mixin_test.rb +95 -0
 - data/test/modules_test.rb +23 -10
 - data/test/multiple_db_test.rb +17 -3
 - data/test/pk_test.rb +59 -15
 - data/test/query_cache_test.rb +104 -0
 - data/test/readonly_test.rb +107 -0
 - data/test/reflection_test.rb +124 -27
 - data/test/reserved_word_test_mysql.rb +177 -0
 - data/test/schema_authorization_test_postgresql.rb +75 -0
 - data/test/schema_dumper_test.rb +131 -0
 - data/test/schema_test_postgresql.rb +64 -0
 - data/test/serialization_test.rb +47 -0
 - data/test/synonym_test_oracle.rb +17 -0
 - data/test/table_name_test_sqlserver.rb +23 -0
 - data/test/threaded_connections_test.rb +48 -0
 - data/test/transactions_test.rb +227 -29
 - data/test/unconnected_test.rb +14 -6
 - data/test/validations_test.rb +1293 -32
 - data/test/xml_serialization_test.rb +202 -0
 - metadata +347 -143
 - data/dev-utils/eval_debugger.rb +0 -9
 - data/examples/associations.rb +0 -87
 - data/examples/shared_setup.rb +0 -15
 - data/examples/validation.rb +0 -88
 - data/lib/active_record/deprecated_associations.rb +0 -70
 - data/lib/active_record/support/class_attribute_accessors.rb +0 -43
 - data/lib/active_record/support/class_inheritable_attributes.rb +0 -37
 - data/lib/active_record/support/clean_logger.rb +0 -10
 - data/lib/active_record/support/inflector.rb +0 -70
 - data/lib/active_record/vendor/simple.rb +0 -702
 - data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
 - data/lib/active_record/wrappings.rb +0 -59
 - data/rakefile +0 -122
 - data/test/deprecated_associations_test.rb +0 -336
 - data/test/fixtures/accounts/signals37 +0 -3
 - data/test/fixtures/accounts/unknown +0 -2
 - data/test/fixtures/companies/first_client +0 -6
 - data/test/fixtures/companies/first_firm +0 -4
 - data/test/fixtures/companies/second_client +0 -6
 - data/test/fixtures/courses/java +0 -2
 - data/test/fixtures/courses/ruby +0 -2
 - data/test/fixtures/customers/david +0 -6
 - data/test/fixtures/db_definitions/mysql.sql +0 -96
 - data/test/fixtures/db_definitions/mysql2.sql +0 -4
 - data/test/fixtures/developers/david +0 -2
 - data/test/fixtures/developers/jamis +0 -2
 - data/test/fixtures/entrants/first +0 -3
 - data/test/fixtures/entrants/second +0 -3
 - data/test/fixtures/entrants/third +0 -3
 - data/test/fixtures/fixture_database.sqlite +0 -0
 - data/test/fixtures/fixture_database_2.sqlite +0 -0
 - data/test/fixtures/movies/first +0 -2
 - data/test/fixtures/movies/second +0 -2
 - data/test/fixtures/projects/action_controller +0 -2
 - data/test/fixtures/projects/active_record +0 -2
 - data/test/fixtures/topics/first +0 -9
 - data/test/fixtures/topics/second +0 -8
 - data/test/inflector_test.rb +0 -104
 - data/test/thread_safety_test.rb +0 -33
 
| 
         @@ -1,32 +1,32 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'observer'
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module ActiveRecord
         
     | 
| 
       4 
     | 
    
         
            -
              # Callbacks are hooks into the lifecycle of an Active Record object that  
     | 
| 
       5 
     | 
    
         
            -
              # before or after an alteration of the object state. This can be used to make sure that associated and 
     | 
| 
       6 
     | 
    
         
            -
              # dependent objects are deleted when destroy is called (by overwriting before_destroy) or to massage attributes
         
     | 
| 
       7 
     | 
    
         
            -
              # before they're validated (by overwriting before_validation). As an example of the callbacks initiated, consider
         
     | 
| 
       8 
     | 
    
         
            -
              # the Base#save call:
         
     | 
| 
       9 
     | 
    
         
            -
              #
         
     | 
| 
       10 
     | 
    
         
            -
              # * (-) save
         
     | 
| 
       11 
     | 
    
         
            -
              # * (-) valid 
     | 
| 
       12 
     | 
    
         
            -
              # * (1) before_validation
         
     | 
| 
       13 
     | 
    
         
            -
              # * (2) before_validation_on_create
         
     | 
| 
       14 
     | 
    
         
            -
              # * (-) validate
         
     | 
| 
       15 
     | 
    
         
            -
              # * (-) validate_on_create
         
     | 
| 
       16 
     | 
    
         
            -
              # * ( 
     | 
| 
       17 
     | 
    
         
            -
              # * ( 
     | 
| 
       18 
     | 
    
         
            -
              # * ( 
     | 
| 
       19 
     | 
    
         
            -
              # * ( 
     | 
| 
       20 
     | 
    
         
            -
              # * (-) create
         
     | 
| 
       21 
     | 
    
         
            -
              # * ( 
     | 
| 
       22 
     | 
    
         
            -
              # * ( 
     | 
| 
       23 
     | 
    
         
            -
              # 
     | 
| 
       24 
     | 
    
         
            -
              # That's a total of  
     | 
| 
       25 
     | 
    
         
            -
              # Active Record  
     | 
| 
      
 4 
     | 
    
         
            +
              # Callbacks are hooks into the lifecycle of an Active Record object that allow you to trigger logic
         
     | 
| 
      
 5 
     | 
    
         
            +
              # before or after an alteration of the object state. This can be used to make sure that associated and
         
     | 
| 
      
 6 
     | 
    
         
            +
              # dependent objects are deleted when destroy is called (by overwriting +before_destroy+) or to massage attributes
         
     | 
| 
      
 7 
     | 
    
         
            +
              # before they're validated (by overwriting +before_validation+). As an example of the callbacks initiated, consider
         
     | 
| 
      
 8 
     | 
    
         
            +
              # the <tt>Base#save</tt> call:
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              # * (-) <tt>save</tt>
         
     | 
| 
      
 11 
     | 
    
         
            +
              # * (-) <tt>valid</tt>
         
     | 
| 
      
 12 
     | 
    
         
            +
              # * (1) <tt>before_validation</tt>
         
     | 
| 
      
 13 
     | 
    
         
            +
              # * (2) <tt>before_validation_on_create</tt>
         
     | 
| 
      
 14 
     | 
    
         
            +
              # * (-) <tt>validate</tt>
         
     | 
| 
      
 15 
     | 
    
         
            +
              # * (-) <tt>validate_on_create</tt>
         
     | 
| 
      
 16 
     | 
    
         
            +
              # * (3) <tt>after_validation</tt>
         
     | 
| 
      
 17 
     | 
    
         
            +
              # * (4) <tt>after_validation_on_create</tt>
         
     | 
| 
      
 18 
     | 
    
         
            +
              # * (5) <tt>before_save</tt>
         
     | 
| 
      
 19 
     | 
    
         
            +
              # * (6) <tt>before_create</tt>
         
     | 
| 
      
 20 
     | 
    
         
            +
              # * (-) <tt>create</tt>
         
     | 
| 
      
 21 
     | 
    
         
            +
              # * (7) <tt>after_create</tt>
         
     | 
| 
      
 22 
     | 
    
         
            +
              # * (8) <tt>after_save</tt>
         
     | 
| 
      
 23 
     | 
    
         
            +
              #
         
     | 
| 
      
 24 
     | 
    
         
            +
              # That's a total of eight callbacks, which gives you immense power to react and prepare for each state in the
         
     | 
| 
      
 25 
     | 
    
         
            +
              # Active Record lifecycle.
         
     | 
| 
       26 
26 
     | 
    
         
             
              #
         
     | 
| 
       27 
27 
     | 
    
         
             
              # Examples:
         
     | 
| 
       28 
28 
     | 
    
         
             
              #   class CreditCard < ActiveRecord::Base
         
     | 
| 
       29 
     | 
    
         
            -
              #     # Strip everything but digits, so the user can specify "555 234 34" or 
     | 
| 
      
 29 
     | 
    
         
            +
              #     # Strip everything but digits, so the user can specify "555 234 34" or
         
     | 
| 
       30 
30 
     | 
    
         
             
              #     # "5552-3434" or both will mean "55523434"
         
     | 
| 
       31 
31 
     | 
    
         
             
              #     def before_validation_on_create
         
     | 
| 
       32 
32 
     | 
    
         
             
              #       self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number")
         
     | 
| 
         @@ -34,18 +34,19 @@ module ActiveRecord 
     | 
|
| 
       34 
34 
     | 
    
         
             
              #   end
         
     | 
| 
       35 
35 
     | 
    
         
             
              #
         
     | 
| 
       36 
36 
     | 
    
         
             
              #   class Subscription < ActiveRecord::Base
         
     | 
| 
       37 
     | 
    
         
            -
              #      
     | 
| 
       38 
     | 
    
         
            -
              # 
     | 
| 
       39 
     | 
    
         
            -
              # 
     | 
| 
       40 
     | 
    
         
            -
              # 
     | 
| 
      
 37 
     | 
    
         
            +
              #     before_create :record_signup
         
     | 
| 
      
 38 
     | 
    
         
            +
              #
         
     | 
| 
      
 39 
     | 
    
         
            +
              #     private
         
     | 
| 
      
 40 
     | 
    
         
            +
              #       def record_signup
         
     | 
| 
      
 41 
     | 
    
         
            +
              #         self.signed_up_on = Date.today
         
     | 
| 
      
 42 
     | 
    
         
            +
              #       end
         
     | 
| 
       41 
43 
     | 
    
         
             
              #   end
         
     | 
| 
       42 
44 
     | 
    
         
             
              #
         
     | 
| 
       43 
45 
     | 
    
         
             
              #   class Firm < ActiveRecord::Base
         
     | 
| 
       44 
46 
     | 
    
         
             
              #     # Destroys the associated clients and people when the firm is destroyed
         
     | 
| 
       45 
     | 
    
         
            -
              #      
     | 
| 
       46 
     | 
    
         
            -
              # 
     | 
| 
       47 
     | 
    
         
            -
              # 
     | 
| 
       48 
     | 
    
         
            -
              #     end
         
     | 
| 
      
 47 
     | 
    
         
            +
              #     before_destroy { |record| Person.destroy_all "firm_id = #{record.id}"   }
         
     | 
| 
      
 48 
     | 
    
         
            +
              #     before_destroy { |record| Client.destroy_all "client_of = #{record.id}" }
         
     | 
| 
      
 49 
     | 
    
         
            +
              #   end
         
     | 
| 
       49 
50 
     | 
    
         
             
              #
         
     | 
| 
       50 
51 
     | 
    
         
             
              # == Inheritable callback queues
         
     | 
| 
       51 
52 
     | 
    
         
             
              #
         
     | 
| 
         @@ -61,8 +62,8 @@ module ActiveRecord 
     | 
|
| 
       61 
62 
     | 
    
         
             
              #     before_destroy :destroy_readers
         
     | 
| 
       62 
63 
     | 
    
         
             
              #   end
         
     | 
| 
       63 
64 
     | 
    
         
             
              #
         
     | 
| 
       64 
     | 
    
         
            -
              # Now, when Topic#destroy is run only +destroy_author+ is called. When Reply#destroy is run both +destroy_author+ and
         
     | 
| 
       65 
     | 
    
         
            -
              # +destroy_readers+  
     | 
| 
      
 65 
     | 
    
         
            +
              # Now, when <tt>Topic#destroy</tt> is run only +destroy_author+ is called. When <tt>Reply#destroy</tt> is run, both +destroy_author+ and
         
     | 
| 
      
 66 
     | 
    
         
            +
              # +destroy_readers+ are called. Contrast this to the situation where we've implemented the save behavior through overwriteable
         
     | 
| 
       66 
67 
     | 
    
         
             
              # methods:
         
     | 
| 
       67 
68 
     | 
    
         
             
              #
         
     | 
| 
       68 
69 
     | 
    
         
             
              #   class Topic < ActiveRecord::Base
         
     | 
| 
         @@ -73,15 +74,19 @@ module ActiveRecord 
     | 
|
| 
       73 
74 
     | 
    
         
             
              #     def before_destroy() destroy_readers end
         
     | 
| 
       74 
75 
     | 
    
         
             
              #   end
         
     | 
| 
       75 
76 
     | 
    
         
             
              #
         
     | 
| 
       76 
     | 
    
         
            -
              # In that case, Reply#destroy would only run +destroy_readers+ and _not_ +destroy_author+. So use the callback macros when 
     | 
| 
       77 
     | 
    
         
            -
              # you want to ensure that a certain callback is called for the entire hierarchy and the regular overwriteable methods 
     | 
| 
       78 
     | 
    
         
            -
              # want to leave it up to each descendent to decide whether they want to call +super+ and trigger the inherited callbacks.
         
     | 
| 
      
 77 
     | 
    
         
            +
              # In that case, <tt>Reply#destroy</tt> would only run +destroy_readers+ and _not_ +destroy_author+. So, use the callback macros when
         
     | 
| 
      
 78 
     | 
    
         
            +
              # you want to ensure that a certain callback is called for the entire hierarchy, and use the regular overwriteable methods
         
     | 
| 
      
 79 
     | 
    
         
            +
              # when you want to leave it up to each descendent to decide whether they want to call +super+ and trigger the inherited callbacks.
         
     | 
| 
      
 80 
     | 
    
         
            +
              #
         
     | 
| 
      
 81 
     | 
    
         
            +
              # *IMPORTANT:* In order for inheritance to work for the callback queues, you must specify the callbacks before specifying the
         
     | 
| 
      
 82 
     | 
    
         
            +
              # associations. Otherwise, you might trigger the loading of a child before the parent has registered the callbacks and they won't
         
     | 
| 
      
 83 
     | 
    
         
            +
              # be inherited.
         
     | 
| 
       79 
84 
     | 
    
         
             
              #
         
     | 
| 
       80 
85 
     | 
    
         
             
              # == Types of callbacks
         
     | 
| 
       81 
86 
     | 
    
         
             
              #
         
     | 
| 
       82 
     | 
    
         
            -
              # There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects, 
     | 
| 
      
 87 
     | 
    
         
            +
              # There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
         
     | 
| 
       83 
88 
     | 
    
         
             
              # inline methods (using a proc), and inline eval methods (using a string). Method references and callback objects are the
         
     | 
| 
       84 
     | 
    
         
            -
              # recommended approaches, inline methods using a proc  
     | 
| 
      
 89 
     | 
    
         
            +
              # recommended approaches, inline methods using a proc are sometimes appropriate (such as for creating mix-ins), and inline
         
     | 
| 
       85 
90 
     | 
    
         
             
              # eval methods are deprecated.
         
     | 
| 
       86 
91 
     | 
    
         
             
              #
         
     | 
| 
       87 
92 
     | 
    
         
             
              # The method reference callbacks work by specifying a protected or private method available in the object, like this:
         
     | 
| 
         @@ -115,8 +120,8 @@ module ActiveRecord 
     | 
|
| 
       115 
120 
     | 
    
         
             
              #     def after_save(record)
         
     | 
| 
       116 
121 
     | 
    
         
             
              #       record.credit_card_number = decrypt(record.credit_card_number)
         
     | 
| 
       117 
122 
     | 
    
         
             
              #     end
         
     | 
| 
       118 
     | 
    
         
            -
              # 
     | 
| 
       119 
     | 
    
         
            -
              #     alias_method : 
     | 
| 
      
 123 
     | 
    
         
            +
              #
         
     | 
| 
      
 124 
     | 
    
         
            +
              #     alias_method :after_find, :after_save
         
     | 
| 
       120 
125 
     | 
    
         
             
              #
         
     | 
| 
       121 
126 
     | 
    
         
             
              #     private
         
     | 
| 
       122 
127 
     | 
    
         
             
              #       def encrypt(value)
         
     | 
| 
         @@ -124,7 +129,7 @@ module ActiveRecord 
     | 
|
| 
       124 
129 
     | 
    
         
             
              #       end
         
     | 
| 
       125 
130 
     | 
    
         
             
              #
         
     | 
| 
       126 
131 
     | 
    
         
             
              #       def decrypt(value)
         
     | 
| 
       127 
     | 
    
         
            -
              #         # Secrecy is  
     | 
| 
      
 132 
     | 
    
         
            +
              #         # Secrecy is unveiled
         
     | 
| 
       128 
133 
     | 
    
         
             
              #       end
         
     | 
| 
       129 
134 
     | 
    
         
             
              #   end
         
     | 
| 
       130 
135 
     | 
    
         
             
              #
         
     | 
| 
         @@ -138,200 +143,199 @@ module ActiveRecord 
     | 
|
| 
       138 
143 
     | 
    
         
             
              #     before_destroy 'self.class.delete_all "parent_id = #{id}"'
         
     | 
| 
       139 
144 
     | 
    
         
             
              #   end
         
     | 
| 
       140 
145 
     | 
    
         
             
              #
         
     | 
| 
       141 
     | 
    
         
            -
              # Notice that single  
     | 
| 
      
 146 
     | 
    
         
            +
              # Notice that single quotes (') are used so the <tt>#{id}</tt> part isn't evaluated until the callback is triggered. Also note that these
         
     | 
| 
       142 
147 
     | 
    
         
             
              # inline callbacks can be stacked just like the regular ones:
         
     | 
| 
       143 
148 
     | 
    
         
             
              #
         
     | 
| 
       144 
149 
     | 
    
         
             
              #   class Topic < ActiveRecord::Base
         
     | 
| 
       145 
     | 
    
         
            -
              #     before_destroy 'self.class.delete_all "parent_id = #{id}"', 
     | 
| 
      
 150 
     | 
    
         
            +
              #     before_destroy 'self.class.delete_all "parent_id = #{id}"',
         
     | 
| 
       146 
151 
     | 
    
         
             
              #                    'puts "Evaluated after parents are destroyed"'
         
     | 
| 
       147 
152 
     | 
    
         
             
              #   end
         
     | 
| 
       148 
153 
     | 
    
         
             
              #
         
     | 
| 
       149 
     | 
    
         
            -
              # == The after_find and after_initialize exceptions
         
     | 
| 
      
 154 
     | 
    
         
            +
              # == The +after_find+ and +after_initialize+ exceptions
         
     | 
| 
       150 
155 
     | 
    
         
             
              #
         
     | 
| 
       151 
     | 
    
         
            -
              # Because after_find and after_initialize  
     | 
| 
       152 
     | 
    
         
            -
              # to implement a simple performance constraint (50% more speed on a simple test case). Unlike all the other callbacks, after_find and
         
     | 
| 
       153 
     | 
    
         
            -
              # after_initialize  
     | 
| 
       154 
     | 
    
         
            -
              #  
     | 
| 
      
 156 
     | 
    
         
            +
              # Because +after_find+ and +after_initialize+ are called for each object found and instantiated by a finder, such as <tt>Base.find(:all)</tt>, we've had
         
     | 
| 
      
 157 
     | 
    
         
            +
              # to implement a simple performance constraint (50% more speed on a simple test case). Unlike all the other callbacks, +after_find+ and
         
     | 
| 
      
 158 
     | 
    
         
            +
              # +after_initialize+ will only be run if an explicit implementation is defined (<tt>def after_find</tt>). In that case, all of the
         
     | 
| 
      
 159 
     | 
    
         
            +
              # callback types will be called.
         
     | 
| 
      
 160 
     | 
    
         
            +
              #
         
     | 
| 
      
 161 
     | 
    
         
            +
              # == <tt>before_validation*</tt> returning statements
         
     | 
| 
      
 162 
     | 
    
         
            +
              #
         
     | 
| 
      
 163 
     | 
    
         
            +
              # If the returning value of a +before_validation+ callback can be evaluated to +false+, the process will be aborted and <tt>Base#save</tt> will return +false+.
         
     | 
| 
      
 164 
     | 
    
         
            +
              # If <tt>Base#save!</tt> is called it will raise a +RecordNotSaved+ exception.
         
     | 
| 
      
 165 
     | 
    
         
            +
              # Nothing will be appended to the errors object.
         
     | 
| 
      
 166 
     | 
    
         
            +
              #
         
     | 
| 
      
 167 
     | 
    
         
            +
              # == Canceling callbacks
         
     | 
| 
      
 168 
     | 
    
         
            +
              #
         
     | 
| 
      
 169 
     | 
    
         
            +
              # If a <tt>before_*</tt> callback returns +false+, all the later callbacks and the associated action are cancelled. If an <tt>after_*</tt> callback returns
         
     | 
| 
      
 170 
     | 
    
         
            +
              # +false+, all the later callbacks are cancelled. Callbacks are generally run in the order they are defined, with the exception of callbacks
         
     | 
| 
      
 171 
     | 
    
         
            +
              # defined as methods on the model, which are called last.
         
     | 
| 
       155 
172 
     | 
    
         
             
              module Callbacks
         
     | 
| 
       156 
     | 
    
         
            -
                CALLBACKS = %w( 
     | 
| 
       157 
     | 
    
         
            -
                  after_find after_initialize before_save after_save before_create after_create before_update after_update before_validation 
     | 
| 
      
 173 
     | 
    
         
            +
                CALLBACKS = %w(
         
     | 
| 
      
 174 
     | 
    
         
            +
                  after_find after_initialize before_save after_save before_create after_create before_update after_update before_validation
         
     | 
| 
       158 
175 
     | 
    
         
             
                  after_validation before_validation_on_create after_validation_on_create before_validation_on_update
         
     | 
| 
       159 
176 
     | 
    
         
             
                  after_validation_on_update before_destroy after_destroy
         
     | 
| 
       160 
177 
     | 
    
         
             
                )
         
     | 
| 
       161 
178 
     | 
    
         | 
| 
       162 
     | 
    
         
            -
                def self. 
     | 
| 
       163 
     | 
    
         
            -
                   
     | 
| 
      
 179 
     | 
    
         
            +
                def self.included(base) #:nodoc:
         
     | 
| 
      
 180 
     | 
    
         
            +
                  base.extend Observable
         
     | 
| 
       164 
181 
     | 
    
         | 
| 
       165 
     | 
    
         
            -
                   
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
                    class << self
         
     | 
| 
       168 
     | 
    
         
            -
                      include Observable
         
     | 
| 
       169 
     | 
    
         
            -
                      alias_method :instantiate_without_callbacks, :instantiate
         
     | 
| 
       170 
     | 
    
         
            -
                      alias_method :instantiate, :instantiate_with_callbacks
         
     | 
| 
       171 
     | 
    
         
            -
                    end
         
     | 
| 
      
 182 
     | 
    
         
            +
                  [:create_or_update, :valid?, :create, :update, :destroy].each do |method|
         
     | 
| 
      
 183 
     | 
    
         
            +
                    base.send :alias_method_chain, method, :callbacks
         
     | 
| 
       172 
184 
     | 
    
         
             
                  end
         
     | 
| 
       173 
185 
     | 
    
         | 
| 
       174 
     | 
    
         
            -
                   
     | 
| 
       175 
     | 
    
         
            -
                     
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
       180 
     | 
    
         
            -
             
     | 
| 
       181 
     | 
    
         
            -
                    alias_method :valid_without_callbacks, :valid?
         
     | 
| 
       182 
     | 
    
         
            -
                    alias_method :valid?, :valid_with_callbacks
         
     | 
| 
       183 
     | 
    
         
            -
             
     | 
| 
       184 
     | 
    
         
            -
                    alias_method :create_without_callbacks, :create
         
     | 
| 
       185 
     | 
    
         
            -
                    alias_method :create, :create_with_callbacks
         
     | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
                    alias_method :update_without_callbacks, :update
         
     | 
| 
       188 
     | 
    
         
            -
                    alias_method :update, :update_with_callbacks
         
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
       190 
     | 
    
         
            -
                    alias_method :destroy_without_callbacks, :destroy
         
     | 
| 
       191 
     | 
    
         
            -
                    alias_method :destroy, :destroy_with_callbacks
         
     | 
| 
      
 186 
     | 
    
         
            +
                  CALLBACKS.each do |method|
         
     | 
| 
      
 187 
     | 
    
         
            +
                    base.class_eval <<-"end_eval"
         
     | 
| 
      
 188 
     | 
    
         
            +
                      def self.#{method}(*callbacks, &block)
         
     | 
| 
      
 189 
     | 
    
         
            +
                        callbacks << block if block_given?
         
     | 
| 
      
 190 
     | 
    
         
            +
                        write_inheritable_array(#{method.to_sym.inspect}, callbacks)
         
     | 
| 
      
 191 
     | 
    
         
            +
                      end
         
     | 
| 
      
 192 
     | 
    
         
            +
                    end_eval
         
     | 
| 
       192 
193 
     | 
    
         
             
                  end
         
     | 
| 
       193 
     | 
    
         
            -
             
     | 
| 
       194 
     | 
    
         
            -
                  CALLBACKS.each { |cb| base.class_eval("def self.#{cb}(*methods) write_inheritable_array(\"#{cb}\", methods) end") }
         
     | 
| 
       195 
194 
     | 
    
         
             
                end
         
     | 
| 
       196 
195 
     | 
    
         | 
| 
       197 
     | 
    
         
            -
                 
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
                    object = instantiate_without_callbacks(record)
         
     | 
| 
       200 
     | 
    
         
            -
                    object.callback(:after_find) if object.respond_to_without_attributes?(:after_find)
         
     | 
| 
       201 
     | 
    
         
            -
                    object.callback(:after_initialize) if object.respond_to_without_attributes?(:after_initialize)
         
     | 
| 
       202 
     | 
    
         
            -
                    object
         
     | 
| 
       203 
     | 
    
         
            -
                  end
         
     | 
| 
       204 
     | 
    
         
            -
                end
         
     | 
| 
      
 196 
     | 
    
         
            +
                # Is called when the object was instantiated by one of the finders, like <tt>Base.find</tt>.
         
     | 
| 
      
 197 
     | 
    
         
            +
                #def after_find() end
         
     | 
| 
       205 
198 
     | 
    
         | 
| 
       206 
     | 
    
         
            -
                # Is called  
     | 
| 
       207 
     | 
    
         
            -
                # 
     | 
| 
      
 199 
     | 
    
         
            +
                # Is called after the object has been instantiated by a call to <tt>Base.new</tt>.
         
     | 
| 
      
 200 
     | 
    
         
            +
                #def after_initialize() end
         
     | 
| 
       208 
201 
     | 
    
         | 
| 
       209 
     | 
    
         
            -
                # Is called  
     | 
| 
       210 
     | 
    
         
            -
                # def after_initialize() end
         
     | 
| 
       211 
     | 
    
         
            -
                def initialize_with_callbacks(attributes = nil) #:nodoc:
         
     | 
| 
       212 
     | 
    
         
            -
                  initialize_without_callbacks(attributes)
         
     | 
| 
       213 
     | 
    
         
            -
                  yield self if block_given?
         
     | 
| 
       214 
     | 
    
         
            -
                  after_initialize if respond_to_without_attributes?(:after_initialize)
         
     | 
| 
       215 
     | 
    
         
            -
                end
         
     | 
| 
       216 
     | 
    
         
            -
                
         
     | 
| 
       217 
     | 
    
         
            -
                # Is called _before_ Base.save (regardless of whether it's a create or update save).
         
     | 
| 
      
 202 
     | 
    
         
            +
                # Is called _before_ <tt>Base.save</tt> (regardless of whether it's a +create+ or +update+ save).
         
     | 
| 
       218 
203 
     | 
    
         
             
                def before_save() end
         
     | 
| 
       219 
204 
     | 
    
         | 
| 
       220 
     | 
    
         
            -
                # Is called _after_ Base.save (regardless of whether it's a create or update save).
         
     | 
| 
      
 205 
     | 
    
         
            +
                # Is called _after_ <tt>Base.save</tt> (regardless of whether it's a +create+ or +update+ save).
         
     | 
| 
      
 206 
     | 
    
         
            +
                #
         
     | 
| 
      
 207 
     | 
    
         
            +
                #  class Contact < ActiveRecord::Base
         
     | 
| 
      
 208 
     | 
    
         
            +
                #    after_save { logger.info( 'New contact saved!' ) }
         
     | 
| 
      
 209 
     | 
    
         
            +
                #  end
         
     | 
| 
       221 
210 
     | 
    
         
             
                def after_save()  end
         
     | 
| 
       222 
211 
     | 
    
         
             
                def create_or_update_with_callbacks #:nodoc:
         
     | 
| 
       223 
     | 
    
         
            -
                  callback(:before_save)
         
     | 
| 
       224 
     | 
    
         
            -
                  create_or_update_without_callbacks
         
     | 
| 
      
 212 
     | 
    
         
            +
                  return false if callback(:before_save) == false
         
     | 
| 
      
 213 
     | 
    
         
            +
                  result = create_or_update_without_callbacks
         
     | 
| 
       225 
214 
     | 
    
         
             
                  callback(:after_save)
         
     | 
| 
      
 215 
     | 
    
         
            +
                  result
         
     | 
| 
       226 
216 
     | 
    
         
             
                end
         
     | 
| 
      
 217 
     | 
    
         
            +
                private :create_or_update_with_callbacks
         
     | 
| 
       227 
218 
     | 
    
         | 
| 
       228 
     | 
    
         
            -
                # Is called _before_ Base.save on new objects that haven't been saved yet (no record exists).
         
     | 
| 
      
 219 
     | 
    
         
            +
                # Is called _before_ <tt>Base.save</tt> on new objects that haven't been saved yet (no record exists).
         
     | 
| 
       229 
220 
     | 
    
         
             
                def before_create() end
         
     | 
| 
       230 
221 
     | 
    
         | 
| 
       231 
     | 
    
         
            -
                # Is called _after_ Base.save on new objects that haven't been saved yet (no record exists).
         
     | 
| 
      
 222 
     | 
    
         
            +
                # Is called _after_ <tt>Base.save</tt> on new objects that haven't been saved yet (no record exists).
         
     | 
| 
       232 
223 
     | 
    
         
             
                def after_create() end
         
     | 
| 
       233 
224 
     | 
    
         
             
                def create_with_callbacks #:nodoc:
         
     | 
| 
       234 
     | 
    
         
            -
                  callback(:before_create)
         
     | 
| 
       235 
     | 
    
         
            -
                  create_without_callbacks
         
     | 
| 
      
 225 
     | 
    
         
            +
                  return false if callback(:before_create) == false
         
     | 
| 
      
 226 
     | 
    
         
            +
                  result = create_without_callbacks
         
     | 
| 
       236 
227 
     | 
    
         
             
                  callback(:after_create)
         
     | 
| 
      
 228 
     | 
    
         
            +
                  result
         
     | 
| 
       237 
229 
     | 
    
         
             
                end
         
     | 
| 
      
 230 
     | 
    
         
            +
                private :create_with_callbacks
         
     | 
| 
       238 
231 
     | 
    
         | 
| 
       239 
     | 
    
         
            -
                # Is called _before_ Base.save on existing objects that  
     | 
| 
      
 232 
     | 
    
         
            +
                # Is called _before_ <tt>Base.save</tt> on existing objects that have a record.
         
     | 
| 
       240 
233 
     | 
    
         
             
                def before_update() end
         
     | 
| 
       241 
234 
     | 
    
         | 
| 
       242 
     | 
    
         
            -
                # Is called _after_ Base.save on existing objects that  
     | 
| 
      
 235 
     | 
    
         
            +
                # Is called _after_ <tt>Base.save</tt> on existing objects that have a record.
         
     | 
| 
       243 
236 
     | 
    
         
             
                def after_update() end
         
     | 
| 
       244 
237 
     | 
    
         | 
| 
       245 
238 
     | 
    
         
             
                def update_with_callbacks #:nodoc:
         
     | 
| 
       246 
     | 
    
         
            -
                  callback(:before_update)
         
     | 
| 
       247 
     | 
    
         
            -
                  update_without_callbacks
         
     | 
| 
      
 239 
     | 
    
         
            +
                  return false if callback(:before_update) == false
         
     | 
| 
      
 240 
     | 
    
         
            +
                  result = update_without_callbacks
         
     | 
| 
       248 
241 
     | 
    
         
             
                  callback(:after_update)
         
     | 
| 
      
 242 
     | 
    
         
            +
                  result
         
     | 
| 
       249 
243 
     | 
    
         
             
                end
         
     | 
| 
      
 244 
     | 
    
         
            +
                private :update_with_callbacks
         
     | 
| 
       250 
245 
     | 
    
         | 
| 
       251 
     | 
    
         
            -
                # Is called _before_ Validations.validate (which is part of the Base.save call).
         
     | 
| 
      
 246 
     | 
    
         
            +
                # Is called _before_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call).
         
     | 
| 
       252 
247 
     | 
    
         
             
                def before_validation() end
         
     | 
| 
       253 
248 
     | 
    
         | 
| 
       254 
     | 
    
         
            -
                # Is called _after_ Validations.validate (which is part of the Base.save call).
         
     | 
| 
      
 249 
     | 
    
         
            +
                # Is called _after_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call).
         
     | 
| 
       255 
250 
     | 
    
         
             
                def after_validation() end
         
     | 
| 
       256 
251 
     | 
    
         | 
| 
       257 
     | 
    
         
            -
                # Is called _before_ Validations.validate (which is part of the Base.save call) on new objects
         
     | 
| 
      
 252 
     | 
    
         
            +
                # Is called _before_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call) on new objects
         
     | 
| 
       258 
253 
     | 
    
         
             
                # that haven't been saved yet (no record exists).
         
     | 
| 
       259 
254 
     | 
    
         
             
                def before_validation_on_create() end
         
     | 
| 
       260 
255 
     | 
    
         | 
| 
       261 
     | 
    
         
            -
                # Is called _after_ Validations.validate (which is part of the Base.save call) on new objects
         
     | 
| 
      
 256 
     | 
    
         
            +
                # Is called _after_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call) on new objects
         
     | 
| 
       262 
257 
     | 
    
         
             
                # that haven't been saved yet (no record exists).
         
     | 
| 
       263 
258 
     | 
    
         
             
                def after_validation_on_create()  end
         
     | 
| 
       264 
259 
     | 
    
         | 
| 
       265 
     | 
    
         
            -
                # Is called _before_ Validations.validate (which is part of the Base.save call) on 
     | 
| 
       266 
     | 
    
         
            -
                # existing objects that  
     | 
| 
      
 260 
     | 
    
         
            +
                # Is called _before_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call) on
         
     | 
| 
      
 261 
     | 
    
         
            +
                # existing objects that have a record.
         
     | 
| 
       267 
262 
     | 
    
         
             
                def before_validation_on_update() end
         
     | 
| 
       268 
263 
     | 
    
         | 
| 
       269 
     | 
    
         
            -
                # Is called _after_ Validations.validate (which is part of the Base.save call) on 
     | 
| 
       270 
     | 
    
         
            -
                # existing objects that  
     | 
| 
      
 264 
     | 
    
         
            +
                # Is called _after_ <tt>Validations.validate</tt> (which is part of the <tt>Base.save</tt> call) on
         
     | 
| 
      
 265 
     | 
    
         
            +
                # existing objects that have a record.
         
     | 
| 
       271 
266 
     | 
    
         
             
                def after_validation_on_update()  end
         
     | 
| 
       272 
267 
     | 
    
         | 
| 
       273 
     | 
    
         
            -
                def valid_with_callbacks #:nodoc:
         
     | 
| 
       274 
     | 
    
         
            -
                  callback(:before_validation)
         
     | 
| 
       275 
     | 
    
         
            -
                  if new_record? then callback(:before_validation_on_create) else callback(:before_validation_on_update) end
         
     | 
| 
      
 268 
     | 
    
         
            +
                def valid_with_callbacks? #:nodoc:
         
     | 
| 
      
 269 
     | 
    
         
            +
                  return false if callback(:before_validation) == false
         
     | 
| 
      
 270 
     | 
    
         
            +
                  if new_record? then result = callback(:before_validation_on_create) else result = callback(:before_validation_on_update) end
         
     | 
| 
      
 271 
     | 
    
         
            +
                  return false if result == false
         
     | 
| 
       276 
272 
     | 
    
         | 
| 
       277 
     | 
    
         
            -
                  result = valid_without_callbacks
         
     | 
| 
      
 273 
     | 
    
         
            +
                  result = valid_without_callbacks?
         
     | 
| 
       278 
274 
     | 
    
         | 
| 
       279 
275 
     | 
    
         
             
                  callback(:after_validation)
         
     | 
| 
       280 
276 
     | 
    
         
             
                  if new_record? then callback(:after_validation_on_create) else callback(:after_validation_on_update) end
         
     | 
| 
       281 
     | 
    
         
            -
             
     | 
| 
      
 277 
     | 
    
         
            +
             
     | 
| 
       282 
278 
     | 
    
         
             
                  return result
         
     | 
| 
       283 
279 
     | 
    
         
             
                end
         
     | 
| 
       284 
280 
     | 
    
         | 
| 
       285 
     | 
    
         
            -
                # Is called _before_ Base.destroy 
     | 
| 
      
 281 
     | 
    
         
            +
                # Is called _before_ <tt>Base.destroy</tt>.
         
     | 
| 
      
 282 
     | 
    
         
            +
                #
         
     | 
| 
      
 283 
     | 
    
         
            +
                # Note: If you need to _destroy_ or _nullify_ associated records first,
         
     | 
| 
      
 284 
     | 
    
         
            +
                # use the <tt>:dependent</tt> option on your associations.
         
     | 
| 
       286 
285 
     | 
    
         
             
                def before_destroy() end
         
     | 
| 
       287 
286 
     | 
    
         | 
| 
       288 
     | 
    
         
            -
                # Is called _after_ Base.destroy (and all the attributes have been frozen).
         
     | 
| 
      
 287 
     | 
    
         
            +
                # Is called _after_ <tt>Base.destroy</tt> (and all the attributes have been frozen).
         
     | 
| 
      
 288 
     | 
    
         
            +
                #
         
     | 
| 
      
 289 
     | 
    
         
            +
                #  class Contact < ActiveRecord::Base
         
     | 
| 
      
 290 
     | 
    
         
            +
                #    after_destroy { |record| logger.info( "Contact #{record.id} was destroyed." ) }
         
     | 
| 
      
 291 
     | 
    
         
            +
                #  end
         
     | 
| 
       289 
292 
     | 
    
         
             
                def after_destroy()  end
         
     | 
| 
       290 
293 
     | 
    
         
             
                def destroy_with_callbacks #:nodoc:
         
     | 
| 
       291 
     | 
    
         
            -
                  callback(:before_destroy)
         
     | 
| 
       292 
     | 
    
         
            -
                  destroy_without_callbacks
         
     | 
| 
      
 294 
     | 
    
         
            +
                  return false if callback(:before_destroy) == false
         
     | 
| 
      
 295 
     | 
    
         
            +
                  result = destroy_without_callbacks
         
     | 
| 
       293 
296 
     | 
    
         
             
                  callback(:after_destroy)
         
     | 
| 
      
 297 
     | 
    
         
            +
                  result
         
     | 
| 
       294 
298 
     | 
    
         
             
                end
         
     | 
| 
       295 
299 
     | 
    
         | 
| 
       296 
     | 
    
         
            -
                 
     | 
| 
       297 
     | 
    
         
            -
                   
     | 
| 
       298 
     | 
    
         
            -
             
     | 
| 
       299 
     | 
    
         
            -
             
     | 
| 
       300 
     | 
    
         
            -
             
     | 
| 
       301 
     | 
    
         
            -
             
     | 
| 
       302 
     | 
    
         
            -
             
     | 
| 
       303 
     | 
    
         
            -
             
     | 
| 
       304 
     | 
    
         
            -
             
     | 
| 
       305 
     | 
    
         
            -
             
     | 
| 
       306 
     | 
    
         
            -
             
     | 
| 
       307 
     | 
    
         
            -
             
     | 
| 
       308 
     | 
    
         
            -
             
     | 
| 
       309 
     | 
    
         
            -
             
     | 
| 
       310 
     | 
    
         
            -
             
     | 
| 
       311 
     | 
    
         
            -
             
     | 
| 
       312 
     | 
    
         
            -
             
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
       314 
     | 
    
         
            -
             
     | 
| 
       315 
     | 
    
         
            -
                       
     | 
| 
       316 
     | 
    
         
            -
                        ActiveRecordError, 
         
     | 
| 
       317 
     | 
    
         
            -
                        "Filters need to be either a symbol, string (to be eval'ed), proc/method, or " +
         
     | 
| 
       318 
     | 
    
         
            -
                        "class implementing a static filter method"
         
     | 
| 
       319 
     | 
    
         
            -
                      )
         
     | 
| 
      
 300 
     | 
    
         
            +
                private
         
     | 
| 
      
 301 
     | 
    
         
            +
                  def callback(method)
         
     | 
| 
      
 302 
     | 
    
         
            +
                    notify(method)
         
     | 
| 
      
 303 
     | 
    
         
            +
             
     | 
| 
      
 304 
     | 
    
         
            +
                    callbacks_for(method).each do |callback|
         
     | 
| 
      
 305 
     | 
    
         
            +
                      result = case callback
         
     | 
| 
      
 306 
     | 
    
         
            +
                        when Symbol
         
     | 
| 
      
 307 
     | 
    
         
            +
                          self.send(callback)
         
     | 
| 
      
 308 
     | 
    
         
            +
                        when String
         
     | 
| 
      
 309 
     | 
    
         
            +
                          eval(callback, binding)
         
     | 
| 
      
 310 
     | 
    
         
            +
                        when Proc, Method
         
     | 
| 
      
 311 
     | 
    
         
            +
                          callback.call(self)
         
     | 
| 
      
 312 
     | 
    
         
            +
                        else
         
     | 
| 
      
 313 
     | 
    
         
            +
                          if callback.respond_to?(method)
         
     | 
| 
      
 314 
     | 
    
         
            +
                            callback.send(method, self)
         
     | 
| 
      
 315 
     | 
    
         
            +
                          else
         
     | 
| 
      
 316 
     | 
    
         
            +
                            raise ActiveRecordError, "Callbacks must be a symbol denoting the method to call, a string to be evaluated, a block to be invoked, or an object responding to the callback method."
         
     | 
| 
      
 317 
     | 
    
         
            +
                          end
         
     | 
| 
      
 318 
     | 
    
         
            +
                      end
         
     | 
| 
      
 319 
     | 
    
         
            +
                      return false if result == false
         
     | 
| 
       320 
320 
     | 
    
         
             
                    end
         
     | 
| 
      
 321 
     | 
    
         
            +
             
     | 
| 
      
 322 
     | 
    
         
            +
                    result = send(method) if respond_to_without_attributes?(method)
         
     | 
| 
      
 323 
     | 
    
         
            +
             
     | 
| 
      
 324 
     | 
    
         
            +
                    return result
         
     | 
| 
      
 325 
     | 
    
         
            +
                  end
         
     | 
| 
      
 326 
     | 
    
         
            +
             
     | 
| 
      
 327 
     | 
    
         
            +
                  def callbacks_for(method)
         
     | 
| 
      
 328 
     | 
    
         
            +
                    self.class.read_inheritable_attribute(method.to_sym) or []
         
     | 
| 
      
 329 
     | 
    
         
            +
                  end
         
     | 
| 
      
 330 
     | 
    
         
            +
             
     | 
| 
      
 331 
     | 
    
         
            +
                  def invoke_and_notify(method)
         
     | 
| 
      
 332 
     | 
    
         
            +
                    notify(method)
         
     | 
| 
      
 333 
     | 
    
         
            +
                    send(method) if respond_to_without_attributes?(method)
         
     | 
| 
      
 334 
     | 
    
         
            +
                  end
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
                  def notify(method) #:nodoc:
         
     | 
| 
      
 337 
     | 
    
         
            +
                    self.class.changed
         
     | 
| 
      
 338 
     | 
    
         
            +
                    self.class.notify_observers(method, self)
         
     | 
| 
       321 
339 
     | 
    
         
             
                  end
         
     | 
| 
       322 
     | 
    
         
            -
                end
         
     | 
| 
       323 
     | 
    
         
            -
                
         
     | 
| 
       324 
     | 
    
         
            -
                def filter_block?(filter)
         
     | 
| 
       325 
     | 
    
         
            -
                  filter.respond_to?("call") && (filter.arity == 1 || filter.arity == -1)
         
     | 
| 
       326 
     | 
    
         
            -
                end
         
     | 
| 
       327 
     | 
    
         
            -
                
         
     | 
| 
       328 
     | 
    
         
            -
                def filter_class?(filter, callback_method)
         
     | 
| 
       329 
     | 
    
         
            -
                  filter.respond_to?(callback_method)
         
     | 
| 
       330 
     | 
    
         
            -
                end
         
     | 
| 
       331 
     | 
    
         
            -
                
         
     | 
| 
       332 
     | 
    
         
            -
                def notify(callback_method) #:nodoc:
         
     | 
| 
       333 
     | 
    
         
            -
                  self.class.changed
         
     | 
| 
       334 
     | 
    
         
            -
                  self.class.notify_observers(callback_method, self)
         
     | 
| 
       335 
     | 
    
         
            -
                end
         
     | 
| 
       336 
340 
     | 
    
         
             
              end
         
     | 
| 
       337 
     | 
    
         
            -
            end
         
     | 
| 
      
 341 
     | 
    
         
            +
            end
         
     |