activerecord 2.3.18 → 3.0.0.beta
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 +105 -34
- data/examples/performance.rb +3 -39
- data/examples/simple.rb +14 -0
- data/lib/active_record.rb +81 -47
- data/lib/active_record/aggregations.rb +1 -3
- data/lib/active_record/association_preload.rb +39 -54
- data/lib/active_record/associations.rb +262 -419
- data/lib/active_record/associations/association_collection.rb +85 -100
- data/lib/active_record/associations/association_proxy.rb +20 -18
- data/lib/active_record/associations/belongs_to_association.rb +8 -8
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +13 -35
- data/lib/active_record/associations/has_many_association.rb +11 -19
- data/lib/active_record/associations/has_many_through_association.rb +30 -183
- data/lib/active_record/associations/has_one_association.rb +10 -10
- data/lib/active_record/associations/has_one_through_association.rb +13 -11
- data/lib/active_record/associations/through_association_scope.rb +153 -0
- data/lib/active_record/attribute_methods.rb +17 -370
- data/lib/active_record/attribute_methods/before_type_cast.rb +33 -0
- data/lib/active_record/attribute_methods/dirty.rb +87 -0
- data/lib/active_record/attribute_methods/primary_key.rb +44 -0
- data/lib/active_record/attribute_methods/query.rb +37 -0
- data/lib/active_record/attribute_methods/read.rb +116 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +60 -0
- data/lib/active_record/attribute_methods/write.rb +37 -0
- data/lib/active_record/autosave_association.rb +20 -41
- data/lib/active_record/base.rb +357 -1180
- data/lib/active_record/batches.rb +10 -16
- data/lib/active_record/callbacks.rb +66 -126
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +17 -13
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +5 -25
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +4 -43
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +3 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +18 -72
- data/lib/active_record/connection_adapters/abstract_adapter.rb +16 -49
- data/lib/active_record/connection_adapters/mysql_adapter.rb +15 -27
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +84 -46
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +9 -3
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +34 -65
- data/lib/active_record/fixtures.rb +21 -25
- data/lib/active_record/locale/en.yml +9 -27
- data/lib/active_record/locking/optimistic.rb +16 -48
- data/lib/active_record/migration.rb +59 -46
- data/lib/active_record/named_scope.rb +85 -92
- data/lib/active_record/nested_attributes.rb +18 -24
- data/lib/active_record/observer.rb +18 -94
- data/lib/active_record/railtie.rb +83 -0
- data/lib/active_record/railties/controller_runtime.rb +38 -0
- data/lib/active_record/railties/databases.rake +477 -0
- data/lib/active_record/railties/subscriber.rb +27 -0
- data/lib/active_record/reflection.rb +2 -15
- data/lib/active_record/relation.rb +339 -0
- data/lib/active_record/relation/calculations.rb +259 -0
- data/lib/active_record/relation/finder_methods.rb +315 -0
- data/lib/active_record/relation/predicate_builder.rb +46 -0
- data/lib/active_record/relation/query_methods.rb +218 -0
- data/lib/active_record/relation/spawn_methods.rb +102 -0
- data/lib/active_record/schema_dumper.rb +10 -6
- data/lib/active_record/serialization.rb +31 -74
- data/lib/active_record/serializers/xml_serializer.rb +33 -121
- data/lib/active_record/session_store.rb +1 -9
- data/lib/active_record/test_case.rb +1 -3
- data/lib/active_record/timestamp.rb +7 -5
- data/lib/active_record/transactions.rb +9 -9
- data/lib/active_record/validations.rb +51 -1100
- data/lib/active_record/validations/associated.rb +47 -0
- data/lib/active_record/validations/uniqueness.rb +181 -0
- data/lib/active_record/version.rb +3 -3
- data/lib/generators/active_record.rb +30 -0
- data/lib/generators/active_record/migration/migration_generator.rb +25 -0
- data/lib/generators/active_record/migration/templates/migration.rb +11 -0
- data/lib/generators/active_record/model/model_generator.rb +33 -0
- data/lib/generators/active_record/model/templates/migration.rb +16 -0
- data/lib/generators/active_record/model/templates/model.rb +5 -0
- data/lib/generators/active_record/observer/observer_generator.rb +15 -0
- data/lib/generators/active_record/observer/templates/observer.rb +2 -0
- data/lib/generators/active_record/session_migration/session_migration_generator.rb +24 -0
- data/lib/generators/active_record/session_migration/templates/migration.rb +16 -0
- metadata +67 -325
- data/RUNNING_UNIT_TESTS +0 -36
- data/Rakefile +0 -268
- data/install.rb +0 -30
- data/lib/active_record/calculations.rb +0 -321
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -57
- data/lib/active_record/dirty.rb +0 -183
- data/lib/active_record/serializers/json_serializer.rb +0 -91
- data/lib/activerecord.rb +0 -2
- data/test/assets/example.log +0 -1
- data/test/assets/flowers.jpg +0 -0
- data/test/cases/aaa_create_tables_test.rb +0 -24
- data/test/cases/active_schema_test_mysql.rb +0 -122
- data/test/cases/active_schema_test_postgresql.rb +0 -24
- data/test/cases/adapter_test.rb +0 -144
- data/test/cases/aggregations_test.rb +0 -167
- data/test/cases/ar_schema_test.rb +0 -32
- data/test/cases/associations/belongs_to_associations_test.rb +0 -438
- data/test/cases/associations/callbacks_test.rb +0 -161
- data/test/cases/associations/cascaded_eager_loading_test.rb +0 -131
- data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +0 -36
- data/test/cases/associations/eager_load_nested_include_test.rb +0 -131
- data/test/cases/associations/eager_load_nested_polymorphic_include.rb +0 -19
- data/test/cases/associations/eager_singularization_test.rb +0 -145
- data/test/cases/associations/eager_test.rb +0 -852
- data/test/cases/associations/extension_test.rb +0 -62
- data/test/cases/associations/habtm_join_table_test.rb +0 -56
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +0 -827
- data/test/cases/associations/has_many_associations_test.rb +0 -1273
- data/test/cases/associations/has_many_through_associations_test.rb +0 -360
- data/test/cases/associations/has_one_associations_test.rb +0 -330
- data/test/cases/associations/has_one_through_associations_test.rb +0 -209
- data/test/cases/associations/inner_join_association_test.rb +0 -93
- data/test/cases/associations/inverse_associations_test.rb +0 -566
- data/test/cases/associations/join_model_test.rb +0 -712
- data/test/cases/associations_test.rb +0 -282
- data/test/cases/attribute_methods_test.rb +0 -305
- data/test/cases/autosave_association_test.rb +0 -1218
- data/test/cases/base_test.rb +0 -2166
- data/test/cases/batches_test.rb +0 -81
- data/test/cases/binary_test.rb +0 -30
- data/test/cases/calculations_test.rb +0 -360
- data/test/cases/callbacks_observers_test.rb +0 -38
- data/test/cases/callbacks_test.rb +0 -438
- data/test/cases/class_inheritable_attributes_test.rb +0 -32
- data/test/cases/column_alias_test.rb +0 -17
- data/test/cases/column_definition_test.rb +0 -70
- data/test/cases/connection_pool_test.rb +0 -25
- data/test/cases/connection_test_firebird.rb +0 -8
- data/test/cases/connection_test_mysql.rb +0 -65
- data/test/cases/copy_table_test_sqlite.rb +0 -80
- data/test/cases/counter_cache_test.rb +0 -84
- data/test/cases/database_statements_test.rb +0 -12
- data/test/cases/datatype_test_postgresql.rb +0 -204
- data/test/cases/date_time_test.rb +0 -37
- data/test/cases/default_test_firebird.rb +0 -16
- data/test/cases/defaults_test.rb +0 -111
- data/test/cases/deprecated_finder_test.rb +0 -30
- data/test/cases/dirty_test.rb +0 -316
- data/test/cases/finder_respond_to_test.rb +0 -76
- data/test/cases/finder_test.rb +0 -1098
- data/test/cases/fixtures_test.rb +0 -661
- data/test/cases/helper.rb +0 -68
- data/test/cases/i18n_test.rb +0 -46
- data/test/cases/inheritance_test.rb +0 -262
- data/test/cases/invalid_date_test.rb +0 -24
- data/test/cases/json_serialization_test.rb +0 -219
- data/test/cases/lifecycle_test.rb +0 -193
- data/test/cases/locking_test.rb +0 -350
- data/test/cases/method_scoping_test.rb +0 -704
- data/test/cases/migration_test.rb +0 -1649
- data/test/cases/migration_test_firebird.rb +0 -124
- data/test/cases/mixin_test.rb +0 -96
- data/test/cases/modules_test.rb +0 -109
- data/test/cases/multiple_db_test.rb +0 -85
- data/test/cases/named_scope_test.rb +0 -372
- data/test/cases/nested_attributes_test.rb +0 -840
- data/test/cases/pk_test.rb +0 -119
- data/test/cases/pooled_connections_test.rb +0 -103
- data/test/cases/query_cache_test.rb +0 -129
- data/test/cases/readonly_test.rb +0 -107
- data/test/cases/reflection_test.rb +0 -234
- data/test/cases/reload_models_test.rb +0 -22
- data/test/cases/repair_helper.rb +0 -50
- data/test/cases/reserved_word_test_mysql.rb +0 -176
- data/test/cases/sanitize_test.rb +0 -25
- data/test/cases/schema_authorization_test_postgresql.rb +0 -75
- data/test/cases/schema_dumper_test.rb +0 -211
- data/test/cases/schema_test_postgresql.rb +0 -178
- data/test/cases/serialization_test.rb +0 -47
- data/test/cases/sp_test_mysql.rb +0 -16
- data/test/cases/synonym_test_oracle.rb +0 -17
- data/test/cases/timestamp_test.rb +0 -75
- data/test/cases/transactions_test.rb +0 -543
- data/test/cases/unconnected_test.rb +0 -32
- data/test/cases/validations_i18n_test.rb +0 -925
- data/test/cases/validations_test.rb +0 -1684
- data/test/cases/xml_serialization_test.rb +0 -240
- data/test/cases/yaml_serialization_test.rb +0 -11
- data/test/config.rb +0 -5
- data/test/connections/jdbc_jdbcderby/connection.rb +0 -18
- data/test/connections/jdbc_jdbch2/connection.rb +0 -18
- data/test/connections/jdbc_jdbchsqldb/connection.rb +0 -18
- data/test/connections/jdbc_jdbcmysql/connection.rb +0 -26
- data/test/connections/jdbc_jdbcpostgresql/connection.rb +0 -26
- data/test/connections/jdbc_jdbcsqlite3/connection.rb +0 -25
- data/test/connections/native_db2/connection.rb +0 -25
- data/test/connections/native_firebird/connection.rb +0 -26
- data/test/connections/native_frontbase/connection.rb +0 -27
- data/test/connections/native_mysql/connection.rb +0 -25
- data/test/connections/native_openbase/connection.rb +0 -21
- data/test/connections/native_oracle/connection.rb +0 -27
- data/test/connections/native_postgresql/connection.rb +0 -21
- data/test/connections/native_sqlite/connection.rb +0 -25
- data/test/connections/native_sqlite3/connection.rb +0 -25
- data/test/connections/native_sqlite3/in_memory_connection.rb +0 -18
- data/test/connections/native_sybase/connection.rb +0 -23
- data/test/fixtures/accounts.yml +0 -29
- 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_addresses.yml +0 -5
- data/test/fixtures/author_favorites.yml +0 -4
- data/test/fixtures/authors.yml +0 -9
- data/test/fixtures/binaries.yml +0 -132
- data/test/fixtures/books.yml +0 -7
- data/test/fixtures/categories.yml +0 -14
- data/test/fixtures/categories/special_categories.yml +0 -9
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +0 -4
- data/test/fixtures/categories_ordered.yml +0 -7
- data/test/fixtures/categories_posts.yml +0 -23
- data/test/fixtures/categorizations.yml +0 -17
- data/test/fixtures/clubs.yml +0 -6
- data/test/fixtures/comments.yml +0 -59
- data/test/fixtures/companies.yml +0 -56
- data/test/fixtures/computers.yml +0 -4
- data/test/fixtures/courses.yml +0 -7
- data/test/fixtures/customers.yml +0 -26
- data/test/fixtures/developers.yml +0 -21
- data/test/fixtures/developers_projects.yml +0 -17
- data/test/fixtures/edges.yml +0 -6
- data/test/fixtures/entrants.yml +0 -14
- data/test/fixtures/faces.yml +0 -11
- data/test/fixtures/fk_test_has_fk.yml +0 -3
- data/test/fixtures/fk_test_has_pk.yml +0 -2
- data/test/fixtures/funny_jokes.yml +0 -10
- data/test/fixtures/interests.yml +0 -33
- data/test/fixtures/items.yml +0 -4
- data/test/fixtures/jobs.yml +0 -7
- data/test/fixtures/legacy_things.yml +0 -3
- data/test/fixtures/mateys.yml +0 -4
- data/test/fixtures/member_types.yml +0 -6
- data/test/fixtures/members.yml +0 -6
- data/test/fixtures/memberships.yml +0 -20
- data/test/fixtures/men.yml +0 -5
- data/test/fixtures/minimalistics.yml +0 -2
- data/test/fixtures/mixed_case_monkeys.yml +0 -6
- data/test/fixtures/mixins.yml +0 -29
- data/test/fixtures/movies.yml +0 -7
- data/test/fixtures/naked/csv/accounts.csv +0 -1
- data/test/fixtures/naked/yml/accounts.yml +0 -1
- data/test/fixtures/naked/yml/companies.yml +0 -1
- data/test/fixtures/naked/yml/courses.yml +0 -1
- data/test/fixtures/organizations.yml +0 -5
- data/test/fixtures/owners.yml +0 -7
- data/test/fixtures/parrots.yml +0 -27
- data/test/fixtures/parrots_pirates.yml +0 -7
- data/test/fixtures/people.yml +0 -15
- data/test/fixtures/pets.yml +0 -14
- data/test/fixtures/pirates.yml +0 -9
- data/test/fixtures/polymorphic_designs.yml +0 -19
- data/test/fixtures/polymorphic_prices.yml +0 -19
- data/test/fixtures/posts.yml +0 -52
- data/test/fixtures/price_estimates.yml +0 -7
- data/test/fixtures/projects.yml +0 -7
- data/test/fixtures/readers.yml +0 -9
- data/test/fixtures/references.yml +0 -17
- data/test/fixtures/reserved_words/distinct.yml +0 -5
- data/test/fixtures/reserved_words/distincts_selects.yml +0 -11
- data/test/fixtures/reserved_words/group.yml +0 -14
- data/test/fixtures/reserved_words/select.yml +0 -8
- data/test/fixtures/reserved_words/values.yml +0 -7
- data/test/fixtures/ships.yml +0 -5
- data/test/fixtures/sponsors.yml +0 -9
- data/test/fixtures/subscribers.yml +0 -7
- data/test/fixtures/subscriptions.yml +0 -12
- data/test/fixtures/taggings.yml +0 -28
- data/test/fixtures/tags.yml +0 -7
- data/test/fixtures/tasks.yml +0 -7
- data/test/fixtures/tees.yml +0 -4
- data/test/fixtures/ties.yml +0 -4
- data/test/fixtures/topics.yml +0 -42
- data/test/fixtures/toys.yml +0 -4
- data/test/fixtures/treasures.yml +0 -10
- data/test/fixtures/vertices.yml +0 -4
- data/test/fixtures/warehouse-things.yml +0 -3
- data/test/fixtures/zines.yml +0 -5
- data/test/migrations/broken/100_migration_that_raises_exception.rb +0 -10
- data/test/migrations/decimal/1_give_me_big_numbers.rb +0 -15
- data/test/migrations/duplicate/1_people_have_last_names.rb +0 -9
- data/test/migrations/duplicate/2_we_need_reminders.rb +0 -12
- data/test/migrations/duplicate/3_foo.rb +0 -7
- data/test/migrations/duplicate/3_innocent_jointable.rb +0 -12
- data/test/migrations/duplicate_names/20080507052938_chunky.rb +0 -7
- data/test/migrations/duplicate_names/20080507053028_chunky.rb +0 -7
- data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +0 -12
- data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +0 -9
- data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +0 -12
- data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +0 -9
- data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +0 -8
- data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +0 -12
- data/test/migrations/missing/1000_people_have_middle_names.rb +0 -9
- data/test/migrations/missing/1_people_have_last_names.rb +0 -9
- data/test/migrations/missing/3_we_need_reminders.rb +0 -12
- data/test/migrations/missing/4_innocent_jointable.rb +0 -12
- data/test/migrations/valid/1_people_have_last_names.rb +0 -9
- data/test/migrations/valid/2_we_need_reminders.rb +0 -12
- data/test/migrations/valid/3_innocent_jointable.rb +0 -12
- data/test/models/author.rb +0 -151
- data/test/models/auto_id.rb +0 -4
- data/test/models/binary.rb +0 -2
- data/test/models/bird.rb +0 -9
- data/test/models/book.rb +0 -4
- data/test/models/categorization.rb +0 -5
- data/test/models/category.rb +0 -34
- data/test/models/citation.rb +0 -6
- data/test/models/club.rb +0 -13
- data/test/models/column_name.rb +0 -3
- data/test/models/comment.rb +0 -29
- data/test/models/company.rb +0 -173
- data/test/models/company_in_module.rb +0 -78
- data/test/models/computer.rb +0 -3
- data/test/models/contact.rb +0 -16
- data/test/models/contract.rb +0 -5
- data/test/models/course.rb +0 -3
- data/test/models/customer.rb +0 -73
- data/test/models/default.rb +0 -2
- data/test/models/developer.rb +0 -101
- data/test/models/edge.rb +0 -5
- data/test/models/entrant.rb +0 -3
- data/test/models/essay.rb +0 -3
- data/test/models/event.rb +0 -3
- data/test/models/event_author.rb +0 -8
- data/test/models/face.rb +0 -7
- data/test/models/guid.rb +0 -2
- data/test/models/interest.rb +0 -5
- data/test/models/invoice.rb +0 -4
- data/test/models/item.rb +0 -7
- data/test/models/job.rb +0 -5
- data/test/models/joke.rb +0 -3
- data/test/models/keyboard.rb +0 -3
- data/test/models/legacy_thing.rb +0 -3
- data/test/models/line_item.rb +0 -3
- data/test/models/man.rb +0 -9
- data/test/models/matey.rb +0 -4
- data/test/models/member.rb +0 -12
- data/test/models/member_detail.rb +0 -5
- data/test/models/member_type.rb +0 -3
- data/test/models/membership.rb +0 -9
- data/test/models/minimalistic.rb +0 -2
- data/test/models/mixed_case_monkey.rb +0 -3
- data/test/models/movie.rb +0 -5
- data/test/models/order.rb +0 -4
- data/test/models/organization.rb +0 -6
- data/test/models/owner.rb +0 -5
- data/test/models/parrot.rb +0 -22
- data/test/models/person.rb +0 -16
- data/test/models/pet.rb +0 -5
- data/test/models/pirate.rb +0 -80
- data/test/models/polymorphic_design.rb +0 -3
- data/test/models/polymorphic_price.rb +0 -3
- data/test/models/post.rb +0 -102
- data/test/models/price_estimate.rb +0 -3
- data/test/models/project.rb +0 -30
- data/test/models/reader.rb +0 -4
- data/test/models/reference.rb +0 -4
- data/test/models/reply.rb +0 -46
- data/test/models/ship.rb +0 -19
- data/test/models/ship_part.rb +0 -7
- data/test/models/sponsor.rb +0 -4
- data/test/models/subject.rb +0 -4
- data/test/models/subscriber.rb +0 -8
- data/test/models/subscription.rb +0 -4
- data/test/models/tag.rb +0 -7
- data/test/models/tagging.rb +0 -10
- data/test/models/task.rb +0 -3
- data/test/models/tee.rb +0 -4
- data/test/models/tie.rb +0 -4
- data/test/models/topic.rb +0 -80
- data/test/models/toy.rb +0 -6
- data/test/models/treasure.rb +0 -8
- data/test/models/vertex.rb +0 -9
- data/test/models/warehouse_thing.rb +0 -5
- data/test/models/zine.rb +0 -3
- data/test/schema/mysql_specific_schema.rb +0 -31
- data/test/schema/postgresql_specific_schema.rb +0 -114
- data/test/schema/schema.rb +0 -550
- data/test/schema/schema2.rb +0 -6
- data/test/schema/sqlite_specific_schema.rb +0 -25
@@ -0,0 +1,102 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module SpawnMethods
|
3
|
+
def spawn
|
4
|
+
clone.reset
|
5
|
+
end
|
6
|
+
|
7
|
+
def merge(r)
|
8
|
+
merged_relation = spawn
|
9
|
+
return merged_relation unless r
|
10
|
+
|
11
|
+
merged_relation = merged_relation.eager_load(r.eager_load_values).preload(r.preload_values).includes(r.includes_values)
|
12
|
+
|
13
|
+
merged_relation.readonly_value = r.readonly_value unless r.readonly_value.nil?
|
14
|
+
merged_relation.limit_value = r.limit_value if r.limit_value.present?
|
15
|
+
merged_relation.lock_value = r.lock_value unless merged_relation.lock_value
|
16
|
+
merged_relation.offset_value = r.offset_value if r.offset_value.present?
|
17
|
+
|
18
|
+
merged_relation = merged_relation.
|
19
|
+
joins(r.joins_values).
|
20
|
+
group(r.group_values).
|
21
|
+
select(r.select_values).
|
22
|
+
from(r.from_value).
|
23
|
+
having(r.having_values)
|
24
|
+
|
25
|
+
merged_relation.order_values = r.order_values if r.order_values.present?
|
26
|
+
|
27
|
+
merged_relation.create_with_value = @create_with_value
|
28
|
+
|
29
|
+
if @create_with_value && r.create_with_value
|
30
|
+
merged_relation.create_with_value = @create_with_value.merge(r.create_with_value)
|
31
|
+
else
|
32
|
+
merged_relation.create_with_value = r.create_with_value || @create_with_value
|
33
|
+
end
|
34
|
+
|
35
|
+
merged_wheres = @where_values
|
36
|
+
|
37
|
+
r.where_values.each do |w|
|
38
|
+
if w.is_a?(Arel::Predicates::Equality)
|
39
|
+
merged_wheres = merged_wheres.reject {|p| p.is_a?(Arel::Predicates::Equality) && p.operand1.name == w.operand1.name }
|
40
|
+
end
|
41
|
+
|
42
|
+
merged_wheres += [w]
|
43
|
+
end
|
44
|
+
|
45
|
+
merged_relation.where_values = merged_wheres
|
46
|
+
|
47
|
+
merged_relation
|
48
|
+
end
|
49
|
+
|
50
|
+
alias :& :merge
|
51
|
+
|
52
|
+
def except(*skips)
|
53
|
+
result = self.class.new(@klass, table)
|
54
|
+
|
55
|
+
(Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).each do |method|
|
56
|
+
result.send(:"#{method}_values=", send(:"#{method}_values")) unless skips.include?(method)
|
57
|
+
end
|
58
|
+
|
59
|
+
Relation::SINGLE_VALUE_METHODS.each do |method|
|
60
|
+
result.send(:"#{method}_value=", send(:"#{method}_value")) unless skips.include?(method)
|
61
|
+
end
|
62
|
+
|
63
|
+
result
|
64
|
+
end
|
65
|
+
|
66
|
+
def only(*onlies)
|
67
|
+
result = self.class.new(@klass, table)
|
68
|
+
|
69
|
+
onlies.each do |only|
|
70
|
+
if (Relation::ASSOCIATION_METHODS + Relation::MULTI_VALUE_METHODS).include?(only)
|
71
|
+
result.send(:"#{only}_values=", send(:"#{only}_values"))
|
72
|
+
elsif Relation::SINGLE_VALUE_METHODS.include?(only)
|
73
|
+
result.send(:"#{only}_value=", send(:"#{only}_value"))
|
74
|
+
else
|
75
|
+
raise "Invalid argument : #{only}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
82
|
+
VALID_FIND_OPTIONS = [ :conditions, :include, :joins, :limit, :offset,
|
83
|
+
:order, :select, :readonly, :group, :having, :from, :lock ]
|
84
|
+
|
85
|
+
def apply_finder_options(options)
|
86
|
+
relation = spawn
|
87
|
+
return relation unless options
|
88
|
+
|
89
|
+
options.assert_valid_keys(VALID_FIND_OPTIONS)
|
90
|
+
|
91
|
+
[:joins, :select, :group, :having, :order, :limit, :offset, :from, :lock, :readonly].each do |finder|
|
92
|
+
relation = relation.send(finder, options[finder]) if options.has_key?(finder)
|
93
|
+
end
|
94
|
+
|
95
|
+
relation = relation.where(options[:conditions]) if options.has_key?(:conditions)
|
96
|
+
relation = relation.includes(options[:include]) if options.has_key?(:include)
|
97
|
+
|
98
|
+
relation
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'stringio'
|
2
|
-
require '
|
2
|
+
require 'active_support/core_ext/big_decimal'
|
3
3
|
|
4
4
|
module ActiveRecord
|
5
5
|
# This class is used to dump the database schema for some connection to some
|
@@ -102,8 +102,15 @@ HEADER
|
|
102
102
|
next if column.name == pk
|
103
103
|
spec = {}
|
104
104
|
spec[:name] = column.name.inspect
|
105
|
-
|
106
|
-
|
105
|
+
|
106
|
+
# AR has an optimisation which handles zero-scale decimals as integers. This
|
107
|
+
# code ensures that the dumper still dumps the column as a decimal.
|
108
|
+
spec[:type] = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) }
|
109
|
+
'decimal'
|
110
|
+
else
|
111
|
+
column.type.to_s
|
112
|
+
end
|
113
|
+
spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && spec[:type] != 'decimal'
|
107
114
|
spec[:precision] = column.precision.inspect if !column.precision.nil?
|
108
115
|
spec[:scale] = column.scale.inspect if !column.scale.nil?
|
109
116
|
spec[:null] = 'false' if !column.null
|
@@ -171,9 +178,6 @@ HEADER
|
|
171
178
|
statment_parts << (':name => ' + index.name.inspect)
|
172
179
|
statment_parts << ':unique => true' if index.unique
|
173
180
|
|
174
|
-
index_lengths = index.lengths.compact if index.lengths.is_a?(Array)
|
175
|
-
statment_parts << (':length => ' + Hash[*index.columns.zip(index.lengths).flatten].inspect) if index_lengths.present?
|
176
|
-
|
177
181
|
' ' + statment_parts.join(', ')
|
178
182
|
end
|
179
183
|
|
@@ -1,101 +1,58 @@
|
|
1
|
-
require 'active_support/json'
|
2
|
-
|
3
1
|
module ActiveRecord #:nodoc:
|
4
2
|
module Serialization
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(record, options = nil)
|
9
|
-
@record = record
|
10
|
-
@options = options ? options.dup : {}
|
11
|
-
end
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
include ActiveModel::Serializers::JSON
|
12
5
|
|
13
|
-
|
14
|
-
|
15
|
-
# for a N level model but is set for the N+1 level models,
|
16
|
-
# then because <tt>:except</tt> is set to a default value, the second
|
17
|
-
# level model can have both <tt>:except</tt> and <tt>:only</tt> set. So if
|
18
|
-
# <tt>:only</tt> is set, always delete <tt>:except</tt>.
|
19
|
-
def serializable_attribute_names
|
20
|
-
attribute_names = @record.attribute_names
|
6
|
+
def serializable_hash(options = nil)
|
7
|
+
options ||= {}
|
21
8
|
|
22
|
-
|
23
|
-
|
24
|
-
attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
|
25
|
-
else
|
26
|
-
options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column)
|
27
|
-
attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
|
28
|
-
end
|
9
|
+
options[:except] = Array.wrap(options[:except]).map { |n| n.to_s }
|
10
|
+
options[:except] |= Array.wrap(self.class.inheritance_column)
|
29
11
|
|
30
|
-
|
31
|
-
end
|
12
|
+
hash = super(options)
|
32
13
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
14
|
+
serializable_add_includes(options) do |association, records, opts|
|
15
|
+
hash[association] = records.is_a?(Enumerable) ?
|
16
|
+
records.map { |r| r.serializable_hash(opts) } :
|
17
|
+
records.serializable_hash(opts)
|
38
18
|
end
|
39
19
|
|
40
|
-
|
41
|
-
|
42
|
-
end
|
20
|
+
hash
|
21
|
+
end
|
43
22
|
|
23
|
+
private
|
44
24
|
# Add associations specified via the <tt>:includes</tt> option.
|
45
25
|
# Expects a block that takes as arguments:
|
46
26
|
# +association+ - name of the association
|
47
27
|
# +records+ - the association record(s) to be serialized
|
48
28
|
# +opts+ - options for the association records
|
49
|
-
def
|
50
|
-
|
51
|
-
base_only_or_except = { :except => options[:except],
|
52
|
-
:only => options[:only] }
|
29
|
+
def serializable_add_includes(options = {})
|
30
|
+
return unless include_associations = options.delete(:include)
|
53
31
|
|
54
|
-
|
55
|
-
|
32
|
+
base_only_or_except = { :except => options[:except],
|
33
|
+
:only => options[:only] }
|
56
34
|
|
57
|
-
|
58
|
-
|
59
|
-
when :has_many, :has_and_belongs_to_many
|
60
|
-
@record.send(association).to_a
|
61
|
-
when :has_one, :belongs_to
|
62
|
-
@record.send(association)
|
63
|
-
end
|
35
|
+
include_has_options = include_associations.is_a?(Hash)
|
36
|
+
associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
|
64
37
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
38
|
+
for association in associations
|
39
|
+
records = case self.class.reflect_on_association(association).macro
|
40
|
+
when :has_many, :has_and_belongs_to_many
|
41
|
+
send(association).to_a
|
42
|
+
when :has_one, :belongs_to
|
43
|
+
send(association)
|
70
44
|
end
|
71
45
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
def serializable_record
|
77
|
-
{}.tap do |serializable_record|
|
78
|
-
serializable_names.each { |name| serializable_record[name] = @record.send(name) }
|
79
|
-
add_includes do |association, records, opts|
|
80
|
-
if records.is_a?(Enumerable)
|
81
|
-
serializable_record[association] = records.collect { |r| self.class.new(r, opts).serializable_record }
|
82
|
-
else
|
83
|
-
serializable_record[association] = self.class.new(records, opts).serializable_record
|
84
|
-
end
|
46
|
+
unless records.nil?
|
47
|
+
association_options = include_has_options ? include_associations[association] : base_only_or_except
|
48
|
+
opts = options.merge(association_options)
|
49
|
+
yield(association, records, opts)
|
85
50
|
end
|
86
51
|
end
|
87
|
-
end
|
88
52
|
|
89
|
-
|
90
|
-
# overwrite to implement
|
53
|
+
options[:include] = include_associations
|
91
54
|
end
|
92
|
-
|
93
|
-
def to_s(&block)
|
94
|
-
serialize(&block)
|
95
|
-
end
|
96
|
-
end
|
97
55
|
end
|
98
56
|
end
|
99
57
|
|
100
58
|
require 'active_record/serializers/xml_serializer'
|
101
|
-
require 'active_record/serializers/json_serializer'
|
@@ -1,5 +1,9 @@
|
|
1
|
+
require 'active_support/core_ext/hash/conversions'
|
2
|
+
|
1
3
|
module ActiveRecord #:nodoc:
|
2
4
|
module Serialization
|
5
|
+
include ActiveModel::Serializers::Xml
|
6
|
+
|
3
7
|
# Builds an XML document to represent the model. Some configuration is
|
4
8
|
# available through +options+. However more complicated cases should
|
5
9
|
# override ActiveRecord::Base#to_xml.
|
@@ -69,6 +73,21 @@ module ActiveRecord #:nodoc:
|
|
69
73
|
# </account>
|
70
74
|
# </firm>
|
71
75
|
#
|
76
|
+
# Additionally, the record being serialized will be passed to a Proc's second
|
77
|
+
# parameter. This allows for ad hoc additions to the resultant document that
|
78
|
+
# incorporate the context of the record being serialized. And by leveraging the
|
79
|
+
# closure created by a Proc, to_xml can be used to add elements that normally fall
|
80
|
+
# outside of the scope of the model -- for example, generating and appending URLs
|
81
|
+
# associated with models.
|
82
|
+
#
|
83
|
+
# proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
|
84
|
+
# firm.to_xml :procs => [ proc ]
|
85
|
+
#
|
86
|
+
# <firm>
|
87
|
+
# # ... normal attributes as shown above ...
|
88
|
+
# <name-reverse>slangis73</name-reverse>
|
89
|
+
# </firm>
|
90
|
+
#
|
72
91
|
# To include deeper levels of associations pass a hash like this:
|
73
92
|
#
|
74
93
|
# firm.to_xml :include => {:account => {}, :clients => {:include => :address}}
|
@@ -152,82 +171,27 @@ module ActiveRecord #:nodoc:
|
|
152
171
|
# end
|
153
172
|
# end
|
154
173
|
def to_xml(options = {}, &block)
|
155
|
-
|
156
|
-
block_given? ? serializer.to_s(&block) : serializer.to_s
|
157
|
-
end
|
158
|
-
|
159
|
-
def from_xml(xml)
|
160
|
-
self.attributes = Hash.from_xml(xml).values.first
|
161
|
-
self
|
174
|
+
XmlSerializer.new(self, options).serialize(&block)
|
162
175
|
end
|
163
176
|
end
|
164
177
|
|
165
|
-
class XmlSerializer <
|
166
|
-
def
|
167
|
-
|
168
|
-
|
169
|
-
builder = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
170
|
-
|
171
|
-
unless options[:skip_instruct]
|
172
|
-
builder.instruct!
|
173
|
-
options[:skip_instruct] = true
|
174
|
-
end
|
175
|
-
|
176
|
-
builder
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def root
|
181
|
-
root = (options[:root] || @record.class.model_name.singular).to_s
|
182
|
-
reformat_name(root)
|
183
|
-
end
|
184
|
-
|
185
|
-
def dasherize?
|
186
|
-
!options.has_key?(:dasherize) || options[:dasherize]
|
187
|
-
end
|
188
|
-
|
189
|
-
def camelize?
|
190
|
-
options.has_key?(:camelize) && options[:camelize]
|
191
|
-
end
|
192
|
-
|
193
|
-
def reformat_name(name)
|
194
|
-
name = name.camelize if camelize?
|
195
|
-
dasherize? ? name.dasherize : name
|
178
|
+
class XmlSerializer < ActiveModel::Serializers::Xml::Serializer #:nodoc:
|
179
|
+
def initialize(*args)
|
180
|
+
super
|
181
|
+
options[:except] |= Array.wrap(@serializable.class.inheritance_column)
|
196
182
|
end
|
197
183
|
|
198
184
|
def serializable_attributes
|
199
|
-
serializable_attribute_names.collect { |name| Attribute.new(name, @
|
185
|
+
serializable_attribute_names.collect { |name| Attribute.new(name, @serializable) }
|
200
186
|
end
|
201
187
|
|
202
188
|
def serializable_method_attributes
|
203
189
|
Array(options[:methods]).inject([]) do |method_attributes, name|
|
204
|
-
method_attributes << MethodAttribute.new(name.to_s, @
|
190
|
+
method_attributes << MethodAttribute.new(name.to_s, @serializable) if @serializable.respond_to?(name.to_s)
|
205
191
|
method_attributes
|
206
192
|
end
|
207
193
|
end
|
208
194
|
|
209
|
-
def add_attributes
|
210
|
-
(serializable_attributes + serializable_method_attributes).each do |attribute|
|
211
|
-
add_tag(attribute)
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def add_procs
|
216
|
-
if procs = options.delete(:procs)
|
217
|
-
[ *procs ].each do |proc|
|
218
|
-
proc.call(options)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
def add_tag(attribute)
|
224
|
-
builder.tag!(
|
225
|
-
reformat_name(attribute.name),
|
226
|
-
attribute.value.to_s,
|
227
|
-
attribute.decorations(!options[:skip_types])
|
228
|
-
)
|
229
|
-
end
|
230
|
-
|
231
195
|
def add_associations(association, records, opts)
|
232
196
|
if records.is_a?(Enumerable)
|
233
197
|
tag = reformat_name(association.to_s)
|
@@ -251,7 +215,7 @@ module ActiveRecord #:nodoc:
|
|
251
215
|
end
|
252
216
|
end
|
253
217
|
else
|
254
|
-
if record = @
|
218
|
+
if record = @serializable.send(association)
|
255
219
|
record.to_xml(opts.merge(:root => association))
|
256
220
|
end
|
257
221
|
end
|
@@ -270,61 +234,19 @@ module ActiveRecord #:nodoc:
|
|
270
234
|
builder.tag!(*args) do
|
271
235
|
add_attributes
|
272
236
|
procs = options.delete(:procs)
|
273
|
-
|
237
|
+
@serializable.send(:serializable_add_includes, options) { |association, records, opts|
|
238
|
+
add_associations(association, records, opts)
|
239
|
+
}
|
274
240
|
options[:procs] = procs
|
275
241
|
add_procs
|
276
242
|
yield builder if block_given?
|
277
243
|
end
|
278
244
|
end
|
279
245
|
|
280
|
-
class Attribute #:nodoc:
|
281
|
-
attr_reader :name, :value, :type
|
282
|
-
|
283
|
-
def initialize(name, record)
|
284
|
-
@name, @record = name, record
|
285
|
-
|
286
|
-
@type = compute_type
|
287
|
-
@value = compute_value
|
288
|
-
end
|
289
|
-
|
290
|
-
# There is a significant speed improvement if the value
|
291
|
-
# does not need to be escaped, as <tt>tag!</tt> escapes all values
|
292
|
-
# to ensure that valid XML is generated. For known binary
|
293
|
-
# values, it is at least an order of magnitude faster to
|
294
|
-
# Base64 encode binary values and directly put them in the
|
295
|
-
# output XML than to pass the original value or the Base64
|
296
|
-
# encoded value to the <tt>tag!</tt> method. It definitely makes
|
297
|
-
# no sense to Base64 encode the value and then give it to
|
298
|
-
# <tt>tag!</tt>, since that just adds additional overhead.
|
299
|
-
def needs_encoding?
|
300
|
-
![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
|
301
|
-
end
|
302
|
-
|
303
|
-
def decorations(include_types = true)
|
304
|
-
decorations = {}
|
305
|
-
|
306
|
-
if type == :binary
|
307
|
-
decorations[:encoding] = 'base64'
|
308
|
-
end
|
309
|
-
|
310
|
-
if include_types && type != :string
|
311
|
-
decorations[:type] = type
|
312
|
-
end
|
313
|
-
|
314
|
-
if value.nil?
|
315
|
-
decorations[:nil] = true
|
316
|
-
end
|
317
|
-
|
318
|
-
decorations
|
319
|
-
end
|
320
|
-
|
246
|
+
class Attribute < ActiveModel::Serializers::Xml::Serializer::Attribute #:nodoc:
|
321
247
|
protected
|
322
248
|
def compute_type
|
323
|
-
type =
|
324
|
-
:yaml
|
325
|
-
else
|
326
|
-
@record.class.columns_hash[name].try(:type)
|
327
|
-
end
|
249
|
+
type = @serializable.class.serialized_attributes.has_key?(name) ? :yaml : @serializable.class.columns_hash[name].type
|
328
250
|
|
329
251
|
case type
|
330
252
|
when :text
|
@@ -335,22 +257,12 @@ module ActiveRecord #:nodoc:
|
|
335
257
|
type
|
336
258
|
end
|
337
259
|
end
|
338
|
-
|
339
|
-
def compute_value
|
340
|
-
value = @record.send(name)
|
341
|
-
|
342
|
-
if formatter = Hash::XML_FORMATTING[type.to_s]
|
343
|
-
value ? formatter.call(value) : nil
|
344
|
-
else
|
345
|
-
value
|
346
|
-
end
|
347
|
-
end
|
348
260
|
end
|
349
261
|
|
350
262
|
class MethodAttribute < Attribute #:nodoc:
|
351
263
|
protected
|
352
264
|
def compute_type
|
353
|
-
Hash::XML_TYPE_NAMES[@
|
265
|
+
Hash::XML_TYPE_NAMES[@serializable.send(name).class.name] || :string
|
354
266
|
end
|
355
267
|
end
|
356
268
|
end
|