active-fedora 6.8.0 → 7.0.0.pre1
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +15 -5
- data/CONTRIBUTING.md +2 -0
- data/Gemfile +0 -2
- data/History.txt +2 -32
- data/README.md +143 -0
- data/Rakefile +5 -7
- data/active-fedora.gemspec +9 -9
- data/gemfiles/rails3.gemfile +11 -0
- data/gemfiles/rails4.gemfile +10 -0
- data/lib/active_fedora.rb +31 -4
- data/lib/active_fedora/association_relation.rb +18 -0
- data/lib/active_fedora/associations.rb +38 -171
- data/lib/active_fedora/associations/association.rb +163 -0
- data/lib/active_fedora/associations/association_scope.rb +39 -0
- data/lib/active_fedora/associations/belongs_to_association.rb +47 -25
- data/lib/active_fedora/associations/builder/association.rb +55 -0
- data/lib/active_fedora/associations/builder/belongs_to.rb +100 -0
- data/lib/active_fedora/associations/builder/collection_association.rb +56 -0
- data/lib/active_fedora/associations/builder/has_and_belongs_to_many.rb +30 -0
- data/lib/active_fedora/associations/builder/has_many.rb +63 -0
- data/lib/active_fedora/associations/builder/singular_association.rb +32 -0
- data/lib/active_fedora/associations/{association_collection.rb → collection_association.rb} +203 -53
- data/lib/active_fedora/associations/collection_proxy.rb +862 -0
- data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +35 -25
- data/lib/active_fedora/associations/has_many_association.rb +36 -11
- data/lib/active_fedora/associations/singular_association.rb +62 -0
- data/lib/active_fedora/attributes.rb +43 -139
- data/lib/active_fedora/autosave_association.rb +317 -0
- data/lib/active_fedora/base.rb +10 -327
- data/lib/active_fedora/callbacks.rb +1 -3
- data/lib/active_fedora/content_model.rb +16 -0
- data/lib/active_fedora/core.rb +151 -0
- data/lib/active_fedora/datastream_attribute.rb +76 -0
- data/lib/active_fedora/datastream_hash.rb +8 -13
- data/lib/active_fedora/datastreams.rb +39 -26
- data/lib/active_fedora/digital_object.rb +2 -2
- data/lib/active_fedora/fedora_attributes.rb +45 -0
- data/lib/active_fedora/fixture_loader.rb +1 -1
- data/lib/active_fedora/indexing.rb +6 -1
- data/lib/active_fedora/model.rb +0 -17
- data/lib/active_fedora/nested_attributes.rb +2 -2
- data/lib/active_fedora/null_relation.rb +7 -0
- data/lib/active_fedora/om_datastream.rb +3 -4
- data/lib/active_fedora/persistence.rb +41 -29
- data/lib/active_fedora/querying.rb +2 -163
- data/lib/active_fedora/rdf.rb +1 -0
- data/lib/active_fedora/rdf/indexing.rb +67 -0
- data/lib/active_fedora/rdf_datastream.rb +2 -50
- data/lib/active_fedora/rdf_node.rb +12 -7
- data/lib/active_fedora/rdf_node/term_proxy.rb +30 -21
- data/lib/active_fedora/rdfxml_rdf_datastream.rb +1 -1
- data/lib/active_fedora/reflection.rb +163 -20
- data/lib/active_fedora/relation.rb +33 -130
- data/lib/active_fedora/relation/calculations.rb +19 -0
- data/lib/active_fedora/relation/delegation.rb +22 -0
- data/lib/active_fedora/relation/finder_methods.rb +247 -0
- data/lib/active_fedora/relation/merger.rb +22 -0
- data/lib/active_fedora/relation/query_methods.rb +58 -0
- data/lib/active_fedora/relation/spawn_methods.rb +46 -0
- data/lib/active_fedora/relationship_graph.rb +0 -2
- data/lib/active_fedora/rels_ext_datastream.rb +1 -4
- data/lib/active_fedora/rubydora_connection.rb +1 -1
- data/lib/active_fedora/scoping.rb +20 -0
- data/lib/active_fedora/scoping/default.rb +38 -0
- data/lib/active_fedora/scoping/named.rb +32 -0
- data/lib/active_fedora/semantic_node.rb +54 -106
- data/lib/active_fedora/serialization.rb +19 -0
- data/lib/active_fedora/sharding.rb +58 -0
- data/lib/active_fedora/solr_digital_object.rb +15 -5
- data/lib/active_fedora/solr_instance_loader.rb +1 -1
- data/lib/active_fedora/solr_service.rb +1 -1
- data/lib/active_fedora/unsaved_digital_object.rb +6 -4
- data/lib/active_fedora/version.rb +1 -1
- data/lib/tasks/active_fedora.rake +3 -0
- data/lib/tasks/active_fedora_dev.rake +6 -5
- data/spec/config_helper.rb +14 -14
- data/spec/integration/associations_spec.rb +168 -455
- data/spec/integration/attributes_spec.rb +12 -11
- data/spec/integration/auditable_spec.rb +11 -11
- data/spec/integration/autosave_association_spec.rb +25 -0
- data/spec/integration/base_spec.rb +163 -163
- data/spec/integration/belongs_to_association_spec.rb +166 -0
- data/spec/integration/bug_spec.rb +7 -7
- data/spec/integration/collection_association_spec.rb +58 -0
- data/spec/integration/complex_rdf_datastream_spec.rb +88 -88
- data/spec/integration/datastream_collections_spec.rb +69 -69
- data/spec/integration/datastream_spec.rb +43 -43
- data/spec/integration/datastreams_spec.rb +63 -63
- data/spec/integration/delete_all_spec.rb +46 -39
- data/spec/integration/fedora_solr_sync_spec.rb +5 -5
- data/spec/integration/field_to_solr_name_spec.rb +34 -0
- data/spec/integration/full_featured_model_spec.rb +100 -101
- data/spec/integration/has_and_belongs_to_many_associations_spec.rb +341 -0
- data/spec/integration/has_many_associations_spec.rb +172 -24
- data/spec/integration/json_serialization_spec.rb +31 -0
- data/spec/integration/load_from_solr_spec.rb +48 -0
- data/spec/integration/model_spec.rb +35 -40
- data/spec/integration/nested_attribute_spec.rb +42 -43
- data/spec/integration/ntriples_datastream_spec.rb +131 -113
- data/spec/integration/om_datastream_spec.rb +67 -67
- data/spec/integration/persistence_spec.rb +7 -7
- data/spec/integration/rdf_nested_attributes_spec.rb +56 -56
- data/spec/integration/relation_delegation_spec.rb +26 -25
- data/spec/integration/relation_spec.rb +42 -0
- data/spec/integration/rels_ext_datastream_spec.rb +20 -20
- data/spec/integration/scoped_query_spec.rb +61 -51
- data/spec/integration/solr_instance_loader_spec.rb +5 -5
- data/spec/integration/solr_service_spec.rb +46 -46
- data/spec/samples/hydra-mods_article_datastream.rb +334 -334
- data/spec/samples/hydra-rights_metadata_datastream.rb +57 -57
- data/spec/samples/marpa-dc_datastream.rb +17 -17
- data/spec/samples/models/audio_record.rb +16 -16
- data/spec/samples/models/image.rb +2 -2
- data/spec/samples/models/mods_article.rb +5 -5
- data/spec/samples/models/oral_history.rb +18 -18
- data/spec/samples/models/seminar.rb +24 -24
- data/spec/samples/models/seminar_audio_file.rb +17 -17
- data/spec/samples/oral_history_sample_model.rb +21 -21
- data/spec/samples/special_thing.rb +14 -14
- data/spec/spec_helper.rb +11 -7
- data/spec/support/an_active_model.rb +2 -8
- data/spec/support/freeze_mocks.rb +12 -0
- data/spec/support/mock_fedora.rb +17 -16
- data/spec/unit/active_fedora_spec.rb +58 -60
- data/spec/unit/attributes_spec.rb +314 -0
- data/spec/unit/base_active_model_spec.rb +28 -27
- data/spec/unit/base_cma_spec.rb +5 -5
- data/spec/unit/base_datastream_management_spec.rb +27 -27
- data/spec/unit/base_extra_spec.rb +76 -48
- data/spec/unit/base_spec.rb +277 -348
- data/spec/unit/callback_spec.rb +18 -19
- data/spec/unit/code_configurator_spec.rb +17 -17
- data/spec/unit/config_spec.rb +8 -16
- data/spec/unit/content_model_spec.rb +79 -60
- data/spec/unit/datastream_collections_spec.rb +229 -229
- data/spec/unit/datastream_spec.rb +51 -63
- data/spec/unit/datastreams_spec.rb +87 -87
- data/spec/unit/file_configurator_spec.rb +217 -217
- data/spec/unit/has_and_belongs_to_many_collection_spec.rb +44 -25
- data/spec/unit/has_many_collection_spec.rb +26 -8
- data/spec/unit/inheritance_spec.rb +13 -12
- data/spec/unit/model_spec.rb +39 -45
- data/spec/unit/nom_datastream_spec.rb +15 -15
- data/spec/unit/ntriples_datastream_spec.rb +123 -118
- data/spec/unit/om_datastream_spec.rb +227 -233
- data/spec/unit/persistence_spec.rb +34 -15
- data/spec/unit/predicates_spec.rb +73 -73
- data/spec/unit/property_spec.rb +17 -9
- data/spec/unit/qualified_dublin_core_datastream_spec.rb +33 -33
- data/spec/unit/query_spec.rb +222 -198
- data/spec/unit/rdf_datastream_spec.rb +21 -28
- data/spec/unit/rdf_list_nested_attributes_spec.rb +34 -34
- data/spec/unit/rdf_list_spec.rb +65 -64
- data/spec/unit/rdf_node_spec.rb +7 -7
- data/spec/unit/rdf_xml_writer_spec.rb +10 -10
- data/spec/unit/rdfxml_rdf_datastream_spec.rb +27 -27
- data/spec/unit/relationship_graph_spec.rb +51 -51
- data/spec/unit/rels_ext_datastream_spec.rb +68 -74
- data/spec/unit/rspec_matchers/belong_to_associated_active_fedora_object_matcher_spec.rb +15 -15
- data/spec/unit/rspec_matchers/have_many_associated_active_fedora_objects_matcher_spec.rb +15 -15
- data/spec/unit/rspec_matchers/have_predicate_matcher_spec.rb +15 -15
- data/spec/unit/rspec_matchers/match_fedora_datastream_matcher_spec.rb +12 -12
- data/spec/unit/rubydora_connection_spec.rb +5 -5
- data/spec/unit/semantic_node_spec.rb +48 -107
- data/spec/unit/serializers_spec.rb +4 -4
- data/spec/unit/service_definitions_spec.rb +26 -26
- data/spec/unit/simple_datastream_spec.rb +17 -17
- data/spec/unit/solr_config_options_spec.rb +29 -28
- data/spec/unit/solr_digital_object_spec.rb +17 -25
- data/spec/unit/solr_service_spec.rb +95 -82
- data/spec/unit/unsaved_digital_object_spec.rb +24 -23
- data/spec/unit/validations_spec.rb +21 -21
- metadata +110 -159
- data/.rspec +0 -1
- data/.rubocop.yml +0 -1
- data/.rubocop_todo.yml +0 -938
- data/CONSOLE_GETTING_STARTED.textile +0 -1
- data/NOKOGIRI_DATASTREAMS.textile +0 -1
- data/README.textile +0 -116
- data/lib/active_fedora/associations/association_proxy.rb +0 -178
- data/lib/active_fedora/delegating.rb +0 -72
- data/lib/active_fedora/nokogiri_datastream.rb +0 -11
- data/spec/integration/delegating_spec.rb +0 -59
- data/spec/rails3_test_app/.gitignore +0 -4
- data/spec/rails3_test_app/.rspec +0 -1
- data/spec/rails3_test_app/Gemfile +0 -40
- data/spec/rails3_test_app/Rakefile +0 -7
- data/spec/rails3_test_app/app/controllers/application_controller.rb +0 -3
- data/spec/rails3_test_app/app/helpers/application_helper.rb +0 -2
- data/spec/rails3_test_app/app/views/layouts/application.html.erb +0 -14
- data/spec/rails3_test_app/config.ru +0 -4
- data/spec/rails3_test_app/config/application.rb +0 -42
- data/spec/rails3_test_app/config/boot.rb +0 -6
- data/spec/rails3_test_app/config/database.yml +0 -22
- data/spec/rails3_test_app/config/environment.rb +0 -5
- data/spec/rails3_test_app/config/environments/development.rb +0 -25
- data/spec/rails3_test_app/config/environments/production.rb +0 -49
- data/spec/rails3_test_app/config/environments/test.rb +0 -35
- data/spec/rails3_test_app/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/rails3_test_app/config/initializers/inflections.rb +0 -10
- data/spec/rails3_test_app/config/initializers/mime_types.rb +0 -5
- data/spec/rails3_test_app/config/initializers/secret_token.rb +0 -7
- data/spec/rails3_test_app/config/initializers/session_store.rb +0 -8
- data/spec/rails3_test_app/config/locales/en.yml +0 -5
- data/spec/rails3_test_app/config/routes.rb +0 -58
- data/spec/rails3_test_app/db/seeds.rb +0 -7
- data/spec/rails3_test_app/run_tests +0 -3
- data/spec/rails3_test_app/script/rails +0 -6
- data/spec/rails3_test_app/spec/spec_helper.rb +0 -27
- data/spec/rails3_test_app/spec/unit/rails_3_init.rb +0 -15
- data/spec/unit/association_proxy_spec.rb +0 -12
- data/spec/unit/base_delegate_spec.rb +0 -197
- data/spec/unit/base_delegate_to_spec.rb +0 -73
@@ -0,0 +1,862 @@
|
|
1
|
+
module ActiveFedora
|
2
|
+
module Associations
|
3
|
+
# Association proxies in Active Fedora are middlemen between the object that
|
4
|
+
# holds the association, known as the <tt>@owner</tt>, and the actual associated
|
5
|
+
# object, known as the <tt>@target</tt>. The kind of association any proxy is
|
6
|
+
# about is available in <tt>@reflection</tt>. That's an instance of the class
|
7
|
+
# ActiveFedora::Reflection::AssociationReflection.
|
8
|
+
#
|
9
|
+
# For example, given
|
10
|
+
#
|
11
|
+
# class Blog < ActiveFedora::Base
|
12
|
+
# has_many :posts
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# blog = Blog.find(:first)
|
16
|
+
#
|
17
|
+
# the association proxy in <tt>blog.posts</tt> has the object in +blog+ as
|
18
|
+
# <tt>@owner</tt>, the collection of its posts as <tt>@target</tt>, and
|
19
|
+
# the <tt>@reflection</tt> object represents a <tt>:has_many</tt> macro.
|
20
|
+
#
|
21
|
+
# This class has most of the basic instance methods removed, and delegates
|
22
|
+
# unknown methods to <tt>@target</tt> via <tt>method_missing</tt>. As a
|
23
|
+
# corner case, it even removes the +class+ method and that's why you get
|
24
|
+
#
|
25
|
+
# blog.posts.class # => Array
|
26
|
+
#
|
27
|
+
# though the object behind <tt>blog.posts</tt> is not an Array, but an
|
28
|
+
# ActiveFedora::Associations::HasManyAssociation.
|
29
|
+
#
|
30
|
+
# The <tt>@target</tt> object is not \loaded until needed. For example,
|
31
|
+
#
|
32
|
+
# blog.posts.count
|
33
|
+
#
|
34
|
+
# is computed directly through Solr and does not trigger by itself the
|
35
|
+
# instantiation of the actual post records.
|
36
|
+
class CollectionProxy < Relation # :nodoc:
|
37
|
+
|
38
|
+
def initialize(association)
|
39
|
+
@association = association
|
40
|
+
super association.klass
|
41
|
+
merge! association.scope
|
42
|
+
end
|
43
|
+
|
44
|
+
def target
|
45
|
+
@association.target
|
46
|
+
end
|
47
|
+
|
48
|
+
def load_target
|
49
|
+
@association.load_target
|
50
|
+
end
|
51
|
+
|
52
|
+
def loaded?
|
53
|
+
@association.loaded?
|
54
|
+
end
|
55
|
+
|
56
|
+
# Works in two ways.
|
57
|
+
#
|
58
|
+
# *First:* Specify a subset of fields to be selected from the result set.
|
59
|
+
#
|
60
|
+
# class Person < ActiveFedora::Base
|
61
|
+
# has_many :pets
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# person.pets
|
65
|
+
# # => [
|
66
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
67
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
68
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
69
|
+
# # ]
|
70
|
+
#
|
71
|
+
# person.pets.select(:name)
|
72
|
+
# # => [
|
73
|
+
# # #<Pet id: nil, name: "Fancy-Fancy">,
|
74
|
+
# # #<Pet id: nil, name: "Spook">,
|
75
|
+
# # #<Pet id: nil, name: "Choo-Choo">
|
76
|
+
# # ]
|
77
|
+
#
|
78
|
+
# person.pets.select([:id, :name])
|
79
|
+
# # => [
|
80
|
+
# # #<Pet id: 1, name: "Fancy-Fancy">,
|
81
|
+
# # #<Pet id: 2, name: "Spook">,
|
82
|
+
# # #<Pet id: 3, name: "Choo-Choo">
|
83
|
+
# # ]
|
84
|
+
#
|
85
|
+
# Be careful because this also means you’re initializing a model
|
86
|
+
# object with only the fields that you’ve selected. If you attempt
|
87
|
+
# to access a field that is not in the initialized record you’ll
|
88
|
+
# receive:
|
89
|
+
#
|
90
|
+
# person.pets.select(:name).first.person_id
|
91
|
+
# # => ActiveModel::MissingAttributeError: missing attribute: person_id
|
92
|
+
#
|
93
|
+
# *Second:* You can pass a block so it can be used just like Array#select.
|
94
|
+
# This build an array of objects from the database for the scope,
|
95
|
+
# converting them into an array and iterating through them using
|
96
|
+
# Array#select.
|
97
|
+
#
|
98
|
+
# person.pets.select { |pet| pet.name =~ /oo/ }
|
99
|
+
# # => [
|
100
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
101
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
102
|
+
# # ]
|
103
|
+
#
|
104
|
+
# person.pets.select(:name) { |pet| pet.name =~ /oo/ }
|
105
|
+
# # => [
|
106
|
+
# # #<Pet id: 2, name: "Spook">,
|
107
|
+
# # #<Pet id: 3, name: "Choo-Choo">
|
108
|
+
# # ]
|
109
|
+
def select(select = nil, &block)
|
110
|
+
@association.select(select, &block)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Finds an object in the collection responding to the +id+. Uses the same
|
114
|
+
# rules as <tt>ActiveFedora::Base.find</tt>. Returns <tt>ActiveFedora::RecordNotFound</tt>
|
115
|
+
# error if the object can not be found.
|
116
|
+
#
|
117
|
+
# class Person < ActiveFedora::Base
|
118
|
+
# has_many :pets
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
# person.pets
|
122
|
+
# # => [
|
123
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
124
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
125
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
126
|
+
# # ]
|
127
|
+
#
|
128
|
+
# person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
|
129
|
+
# person.pets.find(4) # => ActiveFedora::RecordNotFound: Couldn't find Pet with id=4
|
130
|
+
#
|
131
|
+
# person.pets.find(2) { |pet| pet.name.downcase! }
|
132
|
+
# # => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
|
133
|
+
#
|
134
|
+
# person.pets.find(2, 3)
|
135
|
+
# # => [
|
136
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
137
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
138
|
+
# # ]
|
139
|
+
def find(*args, &block)
|
140
|
+
@association.find(*args, &block)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Returns the first record, or the first +n+ records, from the collection.
|
144
|
+
# If the collection is empty, the first form returns +nil+, and the second
|
145
|
+
# form returns an empty array.
|
146
|
+
#
|
147
|
+
# class Person < ActiveFedora::Base
|
148
|
+
# has_many :pets
|
149
|
+
# end
|
150
|
+
#
|
151
|
+
# person.pets
|
152
|
+
# # => [
|
153
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
154
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
155
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
156
|
+
# # ]
|
157
|
+
#
|
158
|
+
# person.pets.first # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
|
159
|
+
#
|
160
|
+
# person.pets.first(2)
|
161
|
+
# # => [
|
162
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
163
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>
|
164
|
+
# # ]
|
165
|
+
#
|
166
|
+
# another_person_without.pets # => []
|
167
|
+
# another_person_without.pets.first # => nil
|
168
|
+
# another_person_without.pets.first(3) # => []
|
169
|
+
def first(*args)
|
170
|
+
@association.first(*args)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Returns the last record, or the last +n+ records, from the collection.
|
174
|
+
# If the collection is empty, the first form returns +nil+, and the second
|
175
|
+
# form returns an empty array.
|
176
|
+
#
|
177
|
+
# class Person < ActiveFedora::Base
|
178
|
+
# has_many :pets
|
179
|
+
# end
|
180
|
+
#
|
181
|
+
# person.pets
|
182
|
+
# # => [
|
183
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
184
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
185
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
186
|
+
# # ]
|
187
|
+
#
|
188
|
+
# person.pets.last # => #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
189
|
+
#
|
190
|
+
# person.pets.last(2)
|
191
|
+
# # => [
|
192
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
193
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
194
|
+
# # ]
|
195
|
+
#
|
196
|
+
# another_person_without.pets # => []
|
197
|
+
# another_person_without.pets.last # => nil
|
198
|
+
# another_person_without.pets.last(3) # => []
|
199
|
+
def last(*args)
|
200
|
+
@association.last(*args)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Returns a new object of the collection type that has been instantiated
|
204
|
+
# with +attributes+ and linked to this object, but have not yet been saved.
|
205
|
+
# You can pass an array of attributes hashes, this will return an array
|
206
|
+
# with the new objects.
|
207
|
+
#
|
208
|
+
# class Person
|
209
|
+
# has_many :pets
|
210
|
+
# end
|
211
|
+
#
|
212
|
+
# person.pets.build
|
213
|
+
# # => #<Pet id: nil, name: nil, person_id: 1>
|
214
|
+
#
|
215
|
+
# person.pets.build(name: 'Fancy-Fancy')
|
216
|
+
# # => #<Pet id: nil, name: "Fancy-Fancy", person_id: 1>
|
217
|
+
#
|
218
|
+
# person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}])
|
219
|
+
# # => [
|
220
|
+
# # #<Pet id: nil, name: "Spook", person_id: 1>,
|
221
|
+
# # #<Pet id: nil, name: "Choo-Choo", person_id: 1>,
|
222
|
+
# # #<Pet id: nil, name: "Brain", person_id: 1>
|
223
|
+
# # ]
|
224
|
+
#
|
225
|
+
# person.pets.size # => 5 # size of the collection
|
226
|
+
# person.pets.count # => 0 # count from database
|
227
|
+
def build(attributes = {}, &block)
|
228
|
+
@association.build(attributes, &block)
|
229
|
+
end
|
230
|
+
|
231
|
+
# Returns a new object of the collection type that has been instantiated with
|
232
|
+
# attributes, linked to this object and that has already been saved (if it
|
233
|
+
# passes the validations).
|
234
|
+
#
|
235
|
+
# class Person
|
236
|
+
# has_many :pets
|
237
|
+
# end
|
238
|
+
#
|
239
|
+
# person.pets.create(name: 'Fancy-Fancy')
|
240
|
+
# # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
|
241
|
+
#
|
242
|
+
# person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}])
|
243
|
+
# # => [
|
244
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
245
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
246
|
+
# # ]
|
247
|
+
#
|
248
|
+
# person.pets.size # => 3
|
249
|
+
# person.pets.count # => 3
|
250
|
+
#
|
251
|
+
# person.pets.find(1, 2, 3)
|
252
|
+
# # => [
|
253
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
254
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
255
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
256
|
+
# # ]
|
257
|
+
def create(attributes = {}, &block)
|
258
|
+
@association.create(attributes, &block)
|
259
|
+
end
|
260
|
+
|
261
|
+
# Like +create+, except that if the record is invalid, raises an exception.
|
262
|
+
#
|
263
|
+
# class Person
|
264
|
+
# has_many :pets
|
265
|
+
# end
|
266
|
+
#
|
267
|
+
# class Pet
|
268
|
+
# validates :name, presence: true
|
269
|
+
# end
|
270
|
+
#
|
271
|
+
# person.pets.create!(name: nil)
|
272
|
+
# # => ActiveFedora::RecordInvalid: Validation failed: Name can't be blank
|
273
|
+
def create!(attributes = {}, &block)
|
274
|
+
@association.create!(attributes, &block)
|
275
|
+
end
|
276
|
+
|
277
|
+
# Add one or more records to the collection by setting their foreign keys
|
278
|
+
# to the association's primary key. Since << flattens its argument list and
|
279
|
+
# inserts each record, +push+ and +concat+ behave identically. Returns +self+
|
280
|
+
# so method calls may be chained.
|
281
|
+
#
|
282
|
+
# class Person < ActiveFedora::Base
|
283
|
+
# pets :has_many
|
284
|
+
# end
|
285
|
+
#
|
286
|
+
# person.pets.size # => 0
|
287
|
+
# person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
|
288
|
+
# person.pets.concat(Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo'))
|
289
|
+
# person.pets.size # => 3
|
290
|
+
#
|
291
|
+
# person.id # => 1
|
292
|
+
# person.pets
|
293
|
+
# # => [
|
294
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
295
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
296
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
297
|
+
# # ]
|
298
|
+
#
|
299
|
+
# person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
|
300
|
+
# person.pets.size # => 5
|
301
|
+
def concat(*records)
|
302
|
+
@association.concat(*records)
|
303
|
+
end
|
304
|
+
|
305
|
+
# Replace this collection with +other_array+. This will perform a diff
|
306
|
+
# and delete/add only records that have changed.
|
307
|
+
#
|
308
|
+
# class Person < ActiveFedora::Base
|
309
|
+
# has_many :pets
|
310
|
+
# end
|
311
|
+
#
|
312
|
+
# person.pets
|
313
|
+
# # => [#<Pet id: 1, name: "Gorby", group: "cats", person_id: 1>]
|
314
|
+
#
|
315
|
+
# other_pets = [Pet.new(name: 'Puff', group: 'celebrities']
|
316
|
+
#
|
317
|
+
# person.pets.replace(other_pets)
|
318
|
+
#
|
319
|
+
# person.pets
|
320
|
+
# # => [#<Pet id: 2, name: "Puff", group: "celebrities", person_id: 1>]
|
321
|
+
#
|
322
|
+
# If the supplied array has an incorrect association type, it raises
|
323
|
+
# an <tt>ActiveFedora::AssociationTypeMismatch</tt> error:
|
324
|
+
#
|
325
|
+
# person.pets.replace(["doo", "ggie", "gaga"])
|
326
|
+
# # => ActiveFedora::AssociationTypeMismatch: Pet expected, got String
|
327
|
+
def replace(other_array)
|
328
|
+
@association.replace(other_array)
|
329
|
+
end
|
330
|
+
|
331
|
+
# Deletes all the records from the collection. For +has_many+ associations,
|
332
|
+
# the deletion is done according to the strategy specified by the <tt>:dependent</tt>
|
333
|
+
# option. Returns an array with the deleted records.
|
334
|
+
#
|
335
|
+
# If no <tt>:dependent</tt> option is given, then it will follow the
|
336
|
+
# default strategy. The default strategy is <tt>:nullify</tt>. This
|
337
|
+
# sets the foreign keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>,
|
338
|
+
# the default strategy is +delete_all+.
|
339
|
+
#
|
340
|
+
# class Person < ActiveFedora::Base
|
341
|
+
# has_many :pets # dependent: :nullify option by default
|
342
|
+
# end
|
343
|
+
#
|
344
|
+
# person.pets.size # => 3
|
345
|
+
# person.pets
|
346
|
+
# # => [
|
347
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
348
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
349
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
350
|
+
# # ]
|
351
|
+
#
|
352
|
+
# person.pets.delete_all
|
353
|
+
# # => [
|
354
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
355
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
356
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
357
|
+
# # ]
|
358
|
+
#
|
359
|
+
# person.pets.size # => 0
|
360
|
+
# person.pets # => []
|
361
|
+
#
|
362
|
+
# Pet.find(1, 2, 3)
|
363
|
+
# # => [
|
364
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>,
|
365
|
+
# # #<Pet id: 2, name: "Spook", person_id: nil>,
|
366
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: nil>
|
367
|
+
# # ]
|
368
|
+
#
|
369
|
+
# If it is set to <tt>:destroy</tt> all the objects from the collection
|
370
|
+
# are removed by calling their +destroy+ method. See +destroy+ for more
|
371
|
+
# information.
|
372
|
+
#
|
373
|
+
# class Person < ActiveFedora::Base
|
374
|
+
# has_many :pets, dependent: :destroy
|
375
|
+
# end
|
376
|
+
#
|
377
|
+
# person.pets.size # => 3
|
378
|
+
# person.pets
|
379
|
+
# # => [
|
380
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
381
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
382
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
383
|
+
# # ]
|
384
|
+
#
|
385
|
+
# person.pets.delete_all
|
386
|
+
# # => [
|
387
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
388
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
389
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
390
|
+
# # ]
|
391
|
+
#
|
392
|
+
# Pet.find(1, 2, 3)
|
393
|
+
# # => ActiveFedora::RecordNotFound
|
394
|
+
#
|
395
|
+
# If it is set to <tt>:delete_all</tt>, all the objects are deleted
|
396
|
+
# *without* calling their +destroy+ method.
|
397
|
+
#
|
398
|
+
# class Person < ActiveFedora::Base
|
399
|
+
# has_many :pets, dependent: :delete_all
|
400
|
+
# end
|
401
|
+
#
|
402
|
+
# person.pets.size # => 3
|
403
|
+
# person.pets
|
404
|
+
# # => [
|
405
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
406
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
407
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
408
|
+
# # ]
|
409
|
+
#
|
410
|
+
# person.pets.delete_all
|
411
|
+
# # => [
|
412
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
413
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
414
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
415
|
+
# # ]
|
416
|
+
#
|
417
|
+
# Pet.find(1, 2, 3)
|
418
|
+
# # => ActiveFedora::RecordNotFound
|
419
|
+
def delete_all
|
420
|
+
@association.delete_all
|
421
|
+
end
|
422
|
+
|
423
|
+
# Deletes the records of the collection directly from the database.
|
424
|
+
# This will _always_ remove the records ignoring the +:dependent+
|
425
|
+
# option.
|
426
|
+
#
|
427
|
+
# class Person < ActiveFedora::Base
|
428
|
+
# has_many :pets
|
429
|
+
# end
|
430
|
+
#
|
431
|
+
# person.pets.size # => 3
|
432
|
+
# person.pets
|
433
|
+
# # => [
|
434
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
435
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
436
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
437
|
+
# # ]
|
438
|
+
#
|
439
|
+
# person.pets.destroy_all
|
440
|
+
#
|
441
|
+
# person.pets.size # => 0
|
442
|
+
# person.pets # => []
|
443
|
+
#
|
444
|
+
# Pet.find(1) # => Couldn't find Pet with id=1
|
445
|
+
def destroy_all
|
446
|
+
@association.destroy_all
|
447
|
+
end
|
448
|
+
|
449
|
+
# Deletes the +records+ supplied and removes them from the collection. For
|
450
|
+
# +has_many+ associations, the deletion is done according to the strategy
|
451
|
+
# specified by the <tt>:dependent</tt> option. Returns an array with the
|
452
|
+
# deleted records.
|
453
|
+
#
|
454
|
+
# If no <tt>:dependent</tt> option is given, then it will follow the default
|
455
|
+
# strategy. The default strategy is <tt>:nullify</tt>. This sets the foreign
|
456
|
+
# keys to <tt>NULL</tt>. For, +has_many+ <tt>:through</tt>, the default
|
457
|
+
# strategy is +delete_all+.
|
458
|
+
#
|
459
|
+
# class Person < ActiveFedora::Base
|
460
|
+
# has_many :pets # dependent: :nullify option by default
|
461
|
+
# end
|
462
|
+
#
|
463
|
+
# person.pets.size # => 3
|
464
|
+
# person.pets
|
465
|
+
# # => [
|
466
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
467
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
468
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
469
|
+
# # ]
|
470
|
+
#
|
471
|
+
# person.pets.delete(Pet.find(1))
|
472
|
+
# # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
|
473
|
+
#
|
474
|
+
# person.pets.size # => 2
|
475
|
+
# person.pets
|
476
|
+
# # => [
|
477
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
478
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
479
|
+
# # ]
|
480
|
+
#
|
481
|
+
# Pet.find(1)
|
482
|
+
# # => #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>
|
483
|
+
#
|
484
|
+
# If it is set to <tt>:destroy</tt> all the +records+ are removed by calling
|
485
|
+
# their +destroy+ method. See +destroy+ for more information.
|
486
|
+
#
|
487
|
+
# class Person < ActiveFedora::Base
|
488
|
+
# has_many :pets, dependent: :destroy
|
489
|
+
# end
|
490
|
+
#
|
491
|
+
# person.pets.size # => 3
|
492
|
+
# person.pets
|
493
|
+
# # => [
|
494
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
495
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
496
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
497
|
+
# # ]
|
498
|
+
#
|
499
|
+
# person.pets.delete(Pet.find(1), Pet.find(3))
|
500
|
+
# # => [
|
501
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
502
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
503
|
+
# # ]
|
504
|
+
#
|
505
|
+
# person.pets.size # => 1
|
506
|
+
# person.pets
|
507
|
+
# # => [#<Pet id: 2, name: "Spook", person_id: 1>]
|
508
|
+
#
|
509
|
+
# Pet.find(1, 3)
|
510
|
+
# # => ActiveFedora::RecordNotFound: Couldn't find all Pets with IDs (1, 3)
|
511
|
+
#
|
512
|
+
# If it is set to <tt>:delete_all</tt>, all the +records+ are deleted
|
513
|
+
# *without* calling their +destroy+ method.
|
514
|
+
#
|
515
|
+
# class Person < ActiveFedora::Base
|
516
|
+
# has_many :pets, dependent: :delete_all
|
517
|
+
# end
|
518
|
+
#
|
519
|
+
# person.pets.size # => 3
|
520
|
+
# person.pets
|
521
|
+
# # => [
|
522
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
523
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
524
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
525
|
+
# # ]
|
526
|
+
#
|
527
|
+
# person.pets.delete(Pet.find(1))
|
528
|
+
# # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
|
529
|
+
#
|
530
|
+
# person.pets.size # => 2
|
531
|
+
# person.pets
|
532
|
+
# # => [
|
533
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
534
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
535
|
+
# # ]
|
536
|
+
#
|
537
|
+
# Pet.find(1)
|
538
|
+
# # => ActiveFedora::RecordNotFound: Couldn't find Pet with id=1
|
539
|
+
#
|
540
|
+
# You can pass +Fixnum+ or +String+ values, it finds the records
|
541
|
+
# responding to the +id+ and executes delete on them.
|
542
|
+
#
|
543
|
+
# class Person < ActiveFedora::Base
|
544
|
+
# has_many :pets
|
545
|
+
# end
|
546
|
+
#
|
547
|
+
# person.pets.size # => 3
|
548
|
+
# person.pets
|
549
|
+
# # => [
|
550
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
551
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
552
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
553
|
+
# # ]
|
554
|
+
#
|
555
|
+
# person.pets.delete("1")
|
556
|
+
# # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
|
557
|
+
#
|
558
|
+
# person.pets.delete(2, 3)
|
559
|
+
# # => [
|
560
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
561
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
562
|
+
# # ]
|
563
|
+
def delete(*records)
|
564
|
+
@association.delete(*records)
|
565
|
+
end
|
566
|
+
|
567
|
+
# Destroys the +records+ supplied and removes them from the collection.
|
568
|
+
# This method will _always_ remove record from the database ignoring
|
569
|
+
# the +:dependent+ option. Returns an array with the removed records.
|
570
|
+
#
|
571
|
+
# class Person < ActiveFedora::Base
|
572
|
+
# has_many :pets
|
573
|
+
# end
|
574
|
+
#
|
575
|
+
# person.pets.size # => 3
|
576
|
+
# person.pets
|
577
|
+
# # => [
|
578
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
579
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
580
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
581
|
+
# # ]
|
582
|
+
#
|
583
|
+
# person.pets.destroy(Pet.find(1))
|
584
|
+
# # => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
|
585
|
+
#
|
586
|
+
# person.pets.size # => 2
|
587
|
+
# person.pets
|
588
|
+
# # => [
|
589
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
590
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
591
|
+
# # ]
|
592
|
+
#
|
593
|
+
# person.pets.destroy(Pet.find(2), Pet.find(3))
|
594
|
+
# # => [
|
595
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
596
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
597
|
+
# # ]
|
598
|
+
#
|
599
|
+
# person.pets.size # => 0
|
600
|
+
# person.pets # => []
|
601
|
+
#
|
602
|
+
# Pet.find(1, 2, 3) # => ActiveFedora::RecordNotFound: Couldn't find all Pets with IDs (1, 2, 3)
|
603
|
+
#
|
604
|
+
# You can pass +Fixnum+ or +String+ values, it finds the records
|
605
|
+
# responding to the +id+ and then deletes them from the database.
|
606
|
+
#
|
607
|
+
# person.pets.size # => 3
|
608
|
+
# person.pets
|
609
|
+
# # => [
|
610
|
+
# # #<Pet id: 4, name: "Benny", person_id: 1>,
|
611
|
+
# # #<Pet id: 5, name: "Brain", person_id: 1>,
|
612
|
+
# # #<Pet id: 6, name: "Boss", person_id: 1>
|
613
|
+
# # ]
|
614
|
+
#
|
615
|
+
# person.pets.destroy("4")
|
616
|
+
# # => #<Pet id: 4, name: "Benny", person_id: 1>
|
617
|
+
#
|
618
|
+
# person.pets.size # => 2
|
619
|
+
# person.pets
|
620
|
+
# # => [
|
621
|
+
# # #<Pet id: 5, name: "Brain", person_id: 1>,
|
622
|
+
# # #<Pet id: 6, name: "Boss", person_id: 1>
|
623
|
+
# # ]
|
624
|
+
#
|
625
|
+
# person.pets.destroy(5, 6)
|
626
|
+
# # => [
|
627
|
+
# # #<Pet id: 5, name: "Brain", person_id: 1>,
|
628
|
+
# # #<Pet id: 6, name: "Boss", person_id: 1>
|
629
|
+
# # ]
|
630
|
+
#
|
631
|
+
# person.pets.size # => 0
|
632
|
+
# person.pets # => []
|
633
|
+
#
|
634
|
+
# Pet.find(4, 5, 6) # => ActiveFedora::RecordNotFound: Couldn't find all Pets with IDs (4, 5, 6)
|
635
|
+
def destroy(*records)
|
636
|
+
@association.destroy(*records)
|
637
|
+
end
|
638
|
+
|
639
|
+
# Specifies whether the records should be unique or not.
|
640
|
+
#
|
641
|
+
# class Person < ActiveFedora::Base
|
642
|
+
# has_many :pets
|
643
|
+
# end
|
644
|
+
#
|
645
|
+
# person.pets.select(:name)
|
646
|
+
# # => [
|
647
|
+
# # #<Pet name: "Fancy-Fancy">,
|
648
|
+
# # #<Pet name: "Fancy-Fancy">
|
649
|
+
# # ]
|
650
|
+
#
|
651
|
+
# person.pets.select(:name).uniq
|
652
|
+
# # => [#<Pet name: "Fancy-Fancy">]
|
653
|
+
def uniq
|
654
|
+
@association.uniq
|
655
|
+
end
|
656
|
+
|
657
|
+
# Count all records using Solr.
|
658
|
+
#
|
659
|
+
# class Person < ActiveFedora::Base
|
660
|
+
# has_many :pets
|
661
|
+
# end
|
662
|
+
#
|
663
|
+
# person.pets.count # => 3
|
664
|
+
# person.pets
|
665
|
+
# # => [
|
666
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
667
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
668
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
669
|
+
# # ]
|
670
|
+
def count(options = {})
|
671
|
+
@association.count(options)
|
672
|
+
end
|
673
|
+
|
674
|
+
# Returns the size of the collection. If the collection hasn't been loaded,
|
675
|
+
# it executes a solr query to find the matching records. Else it calls
|
676
|
+
# <tt>collection.size</tt>.
|
677
|
+
#
|
678
|
+
# If the collection has been already loaded +size+ and +length+ are
|
679
|
+
# equivalent. If not and you are going to need the records anyway
|
680
|
+
# +length+ will take one less query. Otherwise +size+ is more efficient.
|
681
|
+
#
|
682
|
+
# class Person < ActiveFedora::Base
|
683
|
+
# has_many :pets
|
684
|
+
# end
|
685
|
+
#
|
686
|
+
# person.pets.size # => 3
|
687
|
+
# # queries solr for the number of matching records where "person_id_ssi" = 1
|
688
|
+
#
|
689
|
+
# person.pets # This will execute a solr query
|
690
|
+
# # => [
|
691
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
692
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
693
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
694
|
+
# # ]
|
695
|
+
#
|
696
|
+
# person.pets.size # => 3
|
697
|
+
# # Because the collection is already loaded, this will behave like
|
698
|
+
# # collection.size and no Solr count query is executed.
|
699
|
+
def size
|
700
|
+
@association.size
|
701
|
+
end
|
702
|
+
|
703
|
+
# Returns the size of the collection calling +size+ on the target.
|
704
|
+
# If the collection has been already loaded, +length+ and +size+ are
|
705
|
+
# equivalent. If not and you are going to need the records anyway this
|
706
|
+
# method will take one less query. Otherwise +size+ is more efficient.
|
707
|
+
#
|
708
|
+
# class Person < ActiveFedora::Base
|
709
|
+
# has_many :pets
|
710
|
+
# end
|
711
|
+
#
|
712
|
+
# person.pets.length # => 3
|
713
|
+
# # queries solr for the number of matching records where "person_id_ssi" = 1
|
714
|
+
#
|
715
|
+
# # Because the collection is loaded, you can
|
716
|
+
# # call the collection with no additional queries:
|
717
|
+
# person.pets
|
718
|
+
# # => [
|
719
|
+
# # #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
|
720
|
+
# # #<Pet id: 2, name: "Spook", person_id: 1>,
|
721
|
+
# # #<Pet id: 3, name: "Choo-Choo", person_id: 1>
|
722
|
+
# # ]
|
723
|
+
def length
|
724
|
+
@association.length
|
725
|
+
end
|
726
|
+
|
727
|
+
# Returns +true+ if the collection is empty. If the collection has been
|
728
|
+
# loaded or the <tt>:counter_sql</tt> option is provided, it is equivalent
|
729
|
+
# to <tt>collection.size.zero?</tt>. If the collection has not been loaded,
|
730
|
+
# it is equivalent to <tt>collection.exists?</tt>. If the collection has
|
731
|
+
# not already been loaded and you are going to fetch the records anyway it
|
732
|
+
# is better to check <tt>collection.length.zero?</tt>.
|
733
|
+
#
|
734
|
+
# class Person < ActiveFedora::Base
|
735
|
+
# has_many :pets
|
736
|
+
# end
|
737
|
+
#
|
738
|
+
# person.pets.count # => 1
|
739
|
+
# person.pets.empty? # => false
|
740
|
+
#
|
741
|
+
# person.pets.delete_all
|
742
|
+
#
|
743
|
+
# person.pets.count # => 0
|
744
|
+
# person.pets.empty? # => true
|
745
|
+
def empty?
|
746
|
+
@association.empty?
|
747
|
+
end
|
748
|
+
|
749
|
+
# Returns +true+ if the collection is not empty.
|
750
|
+
#
|
751
|
+
# class Person < ActiveFedora::Base
|
752
|
+
# has_many :pets
|
753
|
+
# end
|
754
|
+
#
|
755
|
+
# person.pets.count # => 0
|
756
|
+
# person.pets.any? # => false
|
757
|
+
#
|
758
|
+
# person.pets << Pet.new(name: 'Snoop')
|
759
|
+
# person.pets.count # => 0
|
760
|
+
# person.pets.any? # => true
|
761
|
+
#
|
762
|
+
# You can also pass a block to define criteria. The behavior
|
763
|
+
# is the same, it returns true if the collection based on the
|
764
|
+
# criteria is not empty.
|
765
|
+
#
|
766
|
+
# person.pets
|
767
|
+
# # => [#<Pet name: "Snoop", group: "dogs">]
|
768
|
+
#
|
769
|
+
# person.pets.any? do |pet|
|
770
|
+
# pet.group == 'cats'
|
771
|
+
# end
|
772
|
+
# # => false
|
773
|
+
#
|
774
|
+
# person.pets.any? do |pet|
|
775
|
+
# pet.group == 'dogs'
|
776
|
+
# end
|
777
|
+
# # => true
|
778
|
+
def any?(&block)
|
779
|
+
@association.any?(&block)
|
780
|
+
end
|
781
|
+
|
782
|
+
# Returns true if the collection has more than one record.
|
783
|
+
# Equivalent to <tt>collection.size > 1</tt>.
|
784
|
+
#
|
785
|
+
# class Person < ActiveFedora::Base
|
786
|
+
# has_many :pets
|
787
|
+
# end
|
788
|
+
#
|
789
|
+
# person.pets.count #=> 1
|
790
|
+
# person.pets.many? #=> false
|
791
|
+
#
|
792
|
+
# person.pets << Pet.new(name: 'Snoopy')
|
793
|
+
# person.pets.count #=> 2
|
794
|
+
# person.pets.many? #=> true
|
795
|
+
#
|
796
|
+
# You can also pass a block to define criteria. The
|
797
|
+
# behavior is the same, it returns true if the collection
|
798
|
+
# based on the criteria has more than one record.
|
799
|
+
#
|
800
|
+
# person.pets
|
801
|
+
# # => [
|
802
|
+
# # #<Pet name: "Gorby", group: "cats">,
|
803
|
+
# # #<Pet name: "Puff", group: "cats">,
|
804
|
+
# # #<Pet name: "Snoop", group: "dogs">
|
805
|
+
# # ]
|
806
|
+
#
|
807
|
+
# person.pets.many? do |pet|
|
808
|
+
# pet.group == 'dogs'
|
809
|
+
# end
|
810
|
+
# # => false
|
811
|
+
#
|
812
|
+
# person.pets.many? do |pet|
|
813
|
+
# pet.group == 'cats'
|
814
|
+
# end
|
815
|
+
# # => true
|
816
|
+
def many?(&block)
|
817
|
+
@association.many?(&block)
|
818
|
+
end
|
819
|
+
|
820
|
+
# Returns +true+ if the given object is present in the collection.
|
821
|
+
#
|
822
|
+
# class Person < ActiveFedora::Base
|
823
|
+
# has_many :pets
|
824
|
+
# end
|
825
|
+
#
|
826
|
+
# person.pets # => [#<Pet id: 20, name: "Snoop">]
|
827
|
+
#
|
828
|
+
# person.pets.include?(Pet.find(20)) # => true
|
829
|
+
# person.pets.include?(Pet.find(21)) # => false
|
830
|
+
def include?(record)
|
831
|
+
@association.include?(record)
|
832
|
+
end
|
833
|
+
|
834
|
+
alias_method :new, :build
|
835
|
+
|
836
|
+
def proxy_association
|
837
|
+
@association
|
838
|
+
end
|
839
|
+
|
840
|
+
def to_ary
|
841
|
+
load_target.dup
|
842
|
+
end
|
843
|
+
alias_method :to_a, :to_ary
|
844
|
+
|
845
|
+
def <<(*records)
|
846
|
+
proxy_association.concat(records) && self
|
847
|
+
end
|
848
|
+
alias_method :push, :<<
|
849
|
+
|
850
|
+
def clear
|
851
|
+
delete_all
|
852
|
+
self
|
853
|
+
end
|
854
|
+
|
855
|
+
def reload
|
856
|
+
proxy_association.reload
|
857
|
+
self
|
858
|
+
end
|
859
|
+
|
860
|
+
end
|
861
|
+
end
|
862
|
+
end
|