Active Record 集合 Proxy
Active Record 中的集合 Proxy 在關聯
與其目標
結果集合之間作為中間人。
例如,已給定
class Blog < ActiveRecord::Base
has_many :posts
end
blog = Blog.first
blog.posts
回傳的集合 Proxy 建置於:has_many
關聯
,並委派一組動態文章作為目標
。
此類別透過委派快取將未知的方法委派給關聯
的關聯類別。
在需要時才會載入目標
結果集合。例如,
blog.posts.count
是透過 SQL 直接運算而來,並不自行引發實際記錄的執行個體化。
- #
- A
- B
- C
- D
- E
- F
- I
- L
- M
- N
- P
- R
- S
- T
執行個體公開方法
<<(*records) 連結
透過將其外來金鑰設定到關聯的主鍵,將一個或多個記錄
新增到集合中。由於<<
會展平其引數清單並插入每個記錄,因此push
和 concat
的行為相同。傳回self
,因此可以串連多個追加。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 0
person.pets << Pet.new(name: 'Fancy-Fancy')
person.pets << [Pet.new(name: 'Spook'), Pet.new(name: 'Choo-Choo')]
person.pets.size # => 3
person.id # => 1
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1049 def <<(*records) proxy_association.concat(records) && self end
==(other) 連結
等同於 Array#==
。如果兩個陣列包含相同數量的元素,且每個元素都等於 other
陣列中的對應元素,則傳回 true
,否則傳回 false
。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>
# ]
other = person.pets.to_ary
person.pets == other
# => true
請注意,未持續化的記錄仍可能視為等於
other = [Pet.new(id: 1), Pet.new(id: 2)]
person.pets == other
# => true
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 980 def ==(other) load_target == other end
any?() 連結
如果集合不為空,則傳回 true
。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.count # => 0
person.pets.any? # => false
person.pets << Pet.new(name: 'Snoop')
person.pets.count # => 1
person.pets.any? # => true
當集合尚未載入時未經過濾就直接呼叫等於 collection.exists?
。若你最後還是會載入集合,那麼呼叫 collection.load.any?
會比較好,可以避免額外的查詢。
你也可以傳入一個 block
來定義標準。行為會是一樣的,若根據標準所篩選出來的集合不為空值,則回傳 true。
person.pets
# => [#<Pet name: "Snoop", group: "dogs">]
person.pets.any? do |pet|
pet.group == 'cats'
end
# => false
person.pets.any? do |pet|
pet.group == 'dogs'
end
# => true
來源:在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 836
build(attributes = {}, &block) 連結
傳回一個集合類型的物件,該物件已被指派 attributes
,並且與這個物件連結,但尚未儲存。你可以傳入由屬性雜湊組成的陣列,這會傳回一個包含新物件的陣列。
class Person
has_many :pets
end
person.pets.build
# => #<Pet id: nil, name: nil, person_id: 1>
person.pets.build(name: 'Fancy-Fancy')
# => #<Pet id: nil, name: "Fancy-Fancy", person_id: 1>
person.pets.build([{name: 'Spook'}, {name: 'Choo-Choo'}, {name: 'Brain'}])
# => [
# #<Pet id: nil, name: "Spook", person_id: 1>,
# #<Pet id: nil, name: "Choo-Choo", person_id: 1>,
# #<Pet id: nil, name: "Brain", person_id: 1>
# ]
person.pets.size # => 5 # size of the collection
person.pets.count # => 0 # count from database
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 318 def build(attributes = {}, &block) @association.build(attributes, &block) end
calculate(operation, column_name) 連結
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 724 def calculate(operation, column_name) null_scope? ? scope.calculate(operation, column_name) : super end
clear() 連結
等同於 delete_all
。不同的地方是傳回的是 self
,而不是包含已刪除物件的陣列,因此可以串連方法。有關詳細資訊,請參閱 delete_all
。請注意,由於 delete_all
是透過直接執行 SQL 查詢到資料庫中來移除記錄,因此物件的 updated_at
欄位並未變更。
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1066 def clear delete_all self end
count(column_name = nil, &block) 連結
計數所有記錄。
class Person < ActiveRecord::Base
has_many :pets
end
# This will perform the count using SQL.
person.pets.count # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
傳遞一個區塊將在 SQL 選擇一個人的所有寵物,然後使用 Ruby 執行計數。
person.pets.count { |pet| pet.name.include?('-') } # => 2
來源:在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 733
create(attributes = {}, &block) 連結
傳回一個集合類型的物件,該物件已被指派屬性,連結到這個物件,且已經儲存(如果它通過驗證)。
class Person
has_many :pets
end
person.pets.create(name: 'Fancy-Fancy')
# => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
person.pets.create([{name: 'Spook'}, {name: 'Choo-Choo'}])
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 3
person.pets.count # => 3
person.pets.find(1, 2, 3)
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 349 def create(attributes = {}, &block) @association.create(attributes, &block) end
create!(attributes = {}, &block) 連結
與 create
相似,但如果記錄無效,會擲回例外。
class Person
has_many :pets
end
class Pet
validates :name, presence: true
end
person.pets.create!(name: nil)
# => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 365 def create!(attributes = {}, &block) @association.create!(attributes, &block) end
delete(*records) 連結
根據 `:dependent` 選項指定的策略從集合中刪除所提供的 `records`。若未給定 `:dependent` 選項,將採用預設策略。傳回已刪除記錄的陣列。
`has_many :through` 關聯的預設刪除策略為 `:delete_all`。
`has_many` 關聯的預設刪除策略為 `:nullify`。這會將外來鍵設為 `NULL`。
class Person < ActiveRecord::Base
has_many :pets # dependent: :nullify option by default
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete(Pet.find(1))
# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
person.pets.size # => 2
person.pets
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
Pet.find(1)
# => #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>
若設為 `:destroy`,將呼叫所有 `records` 的 `destroy` 方法來刪除。詳細資訊請參閱 `destroy`。
class Person < ActiveRecord::Base
has_many :pets, dependent: :destroy
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete(Pet.find(1), Pet.find(3))
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 1
person.pets
# => [#<Pet id: 2, name: "Spook", person_id: 1>]
Pet.find(1, 3)
# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 3)
若設為 `:delete_all`,將 **不** 呼叫所有 `records` 的 `destroy` 方法而刪除。
class Person < ActiveRecord::Base
has_many :pets, dependent: :delete_all
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete(Pet.find(1))
# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
person.pets.size # => 2
person.pets
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
Pet.find(1)
# => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=1
你可以傳入 `Integer` 或 `String` 值,它會找出對應於 `id` 的記錄並對其執行刪除動作。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete("1")
# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
person.pets.delete(2, 3)
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 620 def delete(*records) @association.delete(*records).tap { reset_scope } end
delete_all(dependent = nil) 連結
根據 `:dependent` 選項指定的策略從集合中刪除所有記錄。若未給定 `:dependent` 選項,將採用預設策略。
`has_many :through` 關聯的預設刪除策略為 `:delete_all`。
`has_many` 關聯的預設刪除策略為 `:nullify`。這會將外來鍵設為 `NULL`。
class Person < ActiveRecord::Base
has_many :pets # dependent: :nullify option by default
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete_all
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 0
person.pets # => []
Pet.find(1, 2, 3)
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: nil>,
# #<Pet id: 2, name: "Spook", person_id: nil>,
# #<Pet id: 3, name: "Choo-Choo", person_id: nil>
# ]
`has_many` 和 `has_many :through` 依賴項的預設策略為 `:delete_all`,若 `:dependent` 選項設為 `:destroy`。記錄不會執行實體化,也不會觸發任何回呼。
class Person < ActiveRecord::Base
has_many :pets, dependent: :destroy
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete_all
Pet.find(1, 2, 3)
# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
若設為 `:delete_all`,將 **不** 呼叫物體的 `destroy` 方法而刪除。
class Person < ActiveRecord::Base
has_many :pets, dependent: :delete_all
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.delete_all
Pet.find(1, 2, 3)
# => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 474 def delete_all(dependent = nil) @association.delete_all(dependent).tap { reset_scope } end
destroy(*records) 連結
刪除所提供的 `records`,並將它們從集合中移除。此方法會總是從資料庫中移除記錄,忽略 `:dependent` 選項。傳回已刪除記錄的陣列。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.destroy(Pet.find(1))
# => [#<Pet id: 1, name: "Fancy-Fancy", person_id: 1>]
person.pets.size # => 2
person.pets
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.destroy(Pet.find(2), Pet.find(3))
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 0
person.pets # => []
Pet.find(1, 2, 3) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (1, 2, 3)
你可以傳入 `Integer` 或 `String` 值,它會找出對應於 `id` 的記錄,再從資料庫中將它們刪除。
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 4, name: "Benny", person_id: 1>,
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
person.pets.destroy("4")
# => #<Pet id: 4, name: "Benny", person_id: 1>
person.pets.size # => 2
person.pets
# => [
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
person.pets.destroy(5, 6)
# => [
# #<Pet id: 5, name: "Brain", person_id: 1>,
# #<Pet id: 6, name: "Boss", person_id: 1>
# ]
person.pets.size # => 0
person.pets # => []
Pet.find(4, 5, 6) # => ActiveRecord::RecordNotFound: Couldn't find all Pets with 'id': (4, 5, 6)
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 692 def destroy(*records) @association.destroy(*records).tap { reset_scope } end
destroy_all() 連結
直接從資料庫中刪除集合中的記錄,忽略 `:dependent` 選項。記錄會實體化,並呼叫 `before_remove`、`after_remove`、`before_destroy` 和 `after_destroy` 回呼。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 3
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.destroy_all
person.pets.size # => 0
person.pets # => []
Pet.find(1) # => Couldn't find Pet with id=1
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 501 def destroy_all @association.destroy_all.tap { reset_scope } end
distinct(value = true) 連結
指定記錄是否應該是獨特的。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.select(:name)
# => [
# #<Pet name: "Fancy-Fancy">,
# #<Pet name: "Fancy-Fancy">
# ]
person.pets.select(:name).distinct
# => [#<Pet name: "Fancy-Fancy">]
person.pets.select(:name).distinct.distinct(false)
# => [
# #<Pet name: "Fancy-Fancy">,
# #<Pet name: "Fancy-Fancy">
# ]
來源:在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 697
empty?() 連結
如果集合為空,傳回 `true`。如果集合已載入,等同於 `collection.size.zero?`。如果集合未載入,等同於 `!collection.exists?`。如果集合尚未載入,而且你會擷取記錄,最好檢查 `collection.load.empty?`。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.count # => 1
person.pets.empty? # => false
person.pets.delete_all
person.pets.count # => 0
person.pets.empty? # => true
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 831 def empty? @association.empty? end
fifth() 連結
與 first
相同,但僅傳回第 5 筆記錄。
來源:在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 201
find(*args) 連結
在集合中找出回應著 id
的物件。使用與 ActiveRecord::FinderMethods.find
相同的規則。如果找不到物件,傳回 ActiveRecord::RecordNotFound
錯誤。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.find(1) # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
person.pets.find(4) # => ActiveRecord::RecordNotFound: Couldn't find Pet with 'id'=4
person.pets.find(2) { |pet| pet.name.downcase! }
# => #<Pet id: 2, name: "fancy-fancy", person_id: 1>
person.pets.find(2, 3)
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
來源:顯示 | 在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 138 def find(*args) return super if block_given? @association.find(*args) end
first(limit = nil) 連結
從集合中傳回第一筆記錄,或前 n
筆記錄。如果集合為空,第一個形式會傳回 nil
,而第二個形式會傳回一個空陣列。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.first # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
person.pets.first(2)
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>
# ]
another_person_without.pets # => []
another_person_without.pets.first # => nil
another_person_without.pets.first(3) # => []
來源:在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 144
forty_two() 連結
與 first
相同,但僅傳回第 42 筆記錄。又稱為取得「reddit」。
來源:在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 209
fourth() 連結
與 first
相同,但僅傳回第 4 筆記錄。
來源:在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 193
include?(record) 連結
如果給定的 record
出現在集合中,傳回 true
。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets # => [#<Pet id: 20, name: "Snoop">]
person.pets.include?(Pet.find(20)) # => true
person.pets.include?(Pet.find(21)) # => false
來源:顯示 | 在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 927 def include?(record) !!@association.include?(record) end
last(limit = nil) 連結
從集合中傳回最後一筆記錄,或最後 n
筆記錄。如果集合為空,第一個形式會傳回 nil
,而第二個形式會傳回一個空陣列。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.last # => #<Pet id: 3, name: "Choo-Choo", person_id: 1>
person.pets.last(2)
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
another_person_without.pets # => []
another_person_without.pets.last # => nil
another_person_without.pets.last(3) # => []
來源:顯示 | 在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 259 def last(limit = nil) load_target if find_from_target? super end
length() 連結
在目標上呼叫 size
,傳回集合的大小。如果集合已載入,length
和 size
是相等的。如果集合尚未載入而你將需要這些記錄,這個方法會使用較少的查詢。否則,size
的效率較高。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.length # => 3
# executes something like SELECT "pets".* FROM "pets" WHERE "pets"."person_id" = 1
# Because the collection is loaded, you can
# call the collection with no additional queries:
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
來源:在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 787
load_target() 連結
來源:顯示 | 在 GitHub 中
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 44 def load_target @association.load_target end
loaded?() 連結
如果關聯已經載入,傳回 true
,否則傳回 false
。
person.pets.loaded? # => false
person.pets.records
person.pets.loaded? # => true
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 53 def loaded? @association.loaded? end
many?() 連結
如果集合有多筆記錄,傳回 true。等同於 collection.size > 1
。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.count # => 1
person.pets.many? # => false
person.pets << Pet.new(name: 'Snoopy')
person.pets.count # => 2
person.pets.many? # => true
你也可以傳遞 block
來定義標準。行為一致,如果基於標準的集合有多筆記錄,傳回 true。
person.pets
# => [
# #<Pet name: "Gorby", group: "cats">,
# #<Pet name: "Puff", group: "cats">,
# #<Pet name: "Snoop", group: "dogs">
# ]
person.pets.many? do |pet|
pet.group == 'dogs'
end
# => false
person.pets.many? do |pet|
pet.group == 'cats'
end
# => true
來源:在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 877
pluck(*column_names) 連結
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 728 def pluck(*column_names) null_scope? ? scope.pluck(*column_names) : super end
proxy_association() 連結
傳回集合的關聯物件。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.proxy_association
# => #<ActiveRecord::Associations::HasManyAssociation owner="#<Person:0x00>">
傳回與 person.association(:pets)
相同的物件,讓你進行呼叫例如 person.pets.proxy_association.owner
。
更多資訊,請參閱 Associations::ClassMethods
中的關聯擴充。
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 944 def proxy_association @association end
reload() 連結
從資料庫重新載入集合。傳回 self
。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets # fetches pets from the database
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
person.pets # uses the pets cache
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
person.pets.reload # fetches pets from the database
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1085 def reload proxy_association.reload(true) reset_scope end
replace(other_array) 連結
使用 other_array
取代此集合。這會執行變更偵測,並僅刪除/新增已變更的記錄。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [#<Pet id: 1, name: "Gorby", group: "cats", person_id: 1>]
other_pets = [Pet.new(name: 'Puff', group: 'celebrities')]
person.pets.replace(other_pets)
person.pets
# => [#<Pet id: 2, name: "Puff", group: "celebrities", person_id: 1>]
如果提供的陣列的關聯類型不正確,它會引發 ActiveRecord::AssociationTypeMismatch
錯誤
person.pets.replace(["doo", "ggie", "gaga"])
# => ActiveRecord::AssociationTypeMismatch: Pet expected, got String
來源:顯示 | 在 GitHub 上
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 391 def replace(other_array) @association.replace(other_array) end
reset() 連結
卸載關聯。傳回 self
。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets # fetches pets from the database
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
person.pets # uses the pets cache
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
person.pets.reset # clears the pets cache
person.pets # fetches pets from the database
# => [#<Pet id: 1, name: "Snoop", group: "dogs", person_id: 1>]
second() 連結
與 first
相同,但只傳回第二條記錄。
Source: on GitHub
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 177
second_to_last() 連結
與 last
相同,但只傳回倒數第二條記錄。
Source: on GitHub
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 226
select(*fields, &block) 連結
有兩種作用方式。
第一:指定從結果集中選取的欄位子集合。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.select(:name)
# => [
# #<Pet id: nil, name: "Fancy-Fancy">,
# #<Pet id: nil, name: "Spook">,
# #<Pet id: nil, name: "Choo-Choo">
# ]
person.pets.select(:id, :name)
# => [
# #<Pet id: 1, name: "Fancy-Fancy">,
# #<Pet id: 2, name: "Spook">,
# #<Pet id: 3, name: "Choo-Choo">
# ]
請小心,因為這也表示您正在初始化只有您所選欄位的模型物件。如果您嘗試存取不在初始化記錄中的欄位(id
除外),您會收到
person.pets.select(:name).first.person_id
# => ActiveModel::MissingAttributeError: missing attribute 'person_id' for Pet
第二:您可以傳遞一個區塊,以便可像 Array#select
一樣使用。這會為範圍建置一個來自資料庫的物件陣列,將它們轉換成陣列並使用 Array#select
來進行反覆運算。
person.pets.select { |pet| /oo/.match?(pet.name) }
# => [
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
Source: on GitHub
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 59
size() 連結
傳回集合大小。如果集合尚未載入,它會執行 SELECT COUNT(*)
查詢。否則,它會呼叫 collection.size
。
如果集合已經載入,則 size
和 length
相等。如果沒有,而您無論如何都需要記錄,則 length
會進行一次較少的查詢。否則 size
會比較有效率。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets.size # => 3
# executes something like SELECT COUNT(*) FROM "pets" WHERE "pets"."person_id" = 1
person.pets # This will execute a SELECT * FROM query
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.size # => 3
# Because the collection is already loaded, this will behave like
# collection.size and no SQL count query is executed.
take(limit = nil) 連結
根據與 ActiveRecord::FinderMethods.take
相同規則,提供集合中的記錄(如果提供參數則為 N 條記錄)。
class Person < ActiveRecord::Base
has_many :pets
end
person.pets
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>,
# #<Pet id: 3, name: "Choo-Choo", person_id: 1>
# ]
person.pets.take # => #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>
person.pets.take(2)
# => [
# #<Pet id: 1, name: "Fancy-Fancy", person_id: 1>,
# #<Pet id: 2, name: "Spook", person_id: 1>
# ]
another_person_without.pets # => []
another_person_without.pets.take # => nil
another_person_without.pets.take(2) # => []