Spec-Zone.ru › Ruby on Rails 4.1

класс ActiveRecord::Associations::CollectionProxy

Родитель:
Relation

Провайдеры ассоциаций в Active Record являются посредниками между объектом, который содержит ассоциацию, известным как @owner, и фактическим связанным объектом, известным как @target. Тип ассоциации, о которой идет речь в любом провайдере, доступен в @reflection. Это экземпляр класса ActiveRecord::Reflection::AssociationReflection.

Например, если

class Blog < ActiveRecord::Base
  has_many :posts
end

blog = Blog.first

провайдер ассоциации в blog.posts содержит объект в blog в качестве @owner, коллекцию его постов в качестве @target, и объект @reflection представляет макрос :has_many.

Этот класс делегирует неизвестные методы объекту @target через method_missing.

Объект @target загружается только при необходимости. Например,

blog.posts.count

вычисляется напрямую через SQL и сам по себе не вызывает создание фактических записей о постах.

Публичные методы экземпляра

<<(*records) Показать исходный код

Добавляет одну или несколько records в коллекцию, устанавливая их внешние ключи в первичный ключ ассоциации. Возвращает 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>
#    ]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 975
def <<(*records)
  proxy_association.concat(records) && self
end
Также известен как: push, append
==(other) Показать исходный код

Эквивалентно Array#==. Возвращает 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
# => false
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 913
def ==(other)
  load_target == other
end
any?(&block) Показать исходный код

Возвращает 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 # => 0
person.pets.any?  # => true

Вы также можете передать блок для определения критериев. Поведение такое же, он возвращает 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
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 811
def any?(&block)
  @association.any?(&block)
end
append(*records)
Псевдоним для: <<
arel() Показать исходный код
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 867
def arel
  scope.arel
end
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
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 257
def build(attributes = {}, &block)
  @association.build(attributes, &block)
end
Также известен как: new
clear() Показать исходный код

Эквивалентно delete_all. Разница в том, что возвращает self, а не массив с удаленными объектами, поэтому вызовы методов могут быть объединены. См. delete_all для получения дополнительной информации.

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 988
def clear
  delete_all
  self
end
concat(*records) Показать исходный код

Добавляет одну или несколько записей в коллекцию, устанавливая их внешние ключи в первичный ключ ассоциации. Так как << выравнивает свой список аргументов и вставляет каждую запись, push и concat ведут себя одинаково. Возвращает self, поэтому вызовы методов могут быть объединены.

class Person < ActiveRecord::Base
  has_many :pets
end

person.pets.size # => 0
person.pets.concat(Pet.new(name: 'Fancy-Fancy'))
person.pets.concat(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>
#    ]

person.pets.concat([Pet.new(name: 'Brain'), Pet.new(name: 'Benny')])
person.pets.size # => 5
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 332
def concat(*records)
  @association.concat(*records)
end
count(column_name = nil, options = {}) Показать исходный код

Подсчитывает все записи с использованием SQL.

class Person < ActiveRecord::Base
  has_many :pets
end

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>
#    ]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 702
def count(column_name = nil, options = {})
  # TODO: Remove options argument as soon we remove support to
  # activerecord-deprecated_finders.
  @association.count(column_name, options)
end
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>
#    ]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 288
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
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 304
def create!(attributes = {}, &block)
  @association.create!(attributes, &block)
end
delete(*records) Показать исходный код

Удаляет предоставленные records и удаляет их из коллекции. Для ассоциаций has_many удаление выполняется в соответствии со стратегией, указанной параметром :dependent. Возвращает массив с удаленными записями.

Если параметр :dependent не указан, то будет использоваться стратегия по умолчанию. Стратегия по умолчанию - :nullify. Это устанавливает внешние ключи в NULL. Для, has_many :through, стратегия по умолчанию - delete_all.

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 IDs (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

Вы можете передать значения Fixnum или String, он находит записи, соответствующие id, и выполняет для них delete.

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>
#    ]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 594
def delete(*records)
  @association.delete(*records)
end
delete_all(dependent = nil) Показать исходный код

Удаляет все записи из коллекции. Для ассоциаций has_many удаление выполняется в соответствии со стратегией, указанной параметром :dependent. Возвращает массив с удаленными записями.

Если параметр :dependent не указан, то будет использоваться стратегия по умолчанию. Стратегия по умолчанию - :nullify. Это устанавливает внешние ключи в NULL. Для, has_many :through, стратегия по умолчанию - delete_all.

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>
#    ]

Если он установлен в :destroy, все объекты из коллекции удаляются путем вызова их метода 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_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>
#    ]

Pet.find(1, 2, 3)
# => ActiveRecord::RecordNotFound

Если он установлен в :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 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>
#    ]

Pet.find(1, 2, 3)
# => ActiveRecord::RecordNotFound
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 450
def delete_all(dependent = nil)
  @association.delete_all(dependent)
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 IDs (1, 2, 3)

Вы можете передать значения Fixnum или 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 IDs (4, 5, 6)
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 666
def destroy(*records)
  @association.destroy(*records)
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
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 476
def destroy_all
  @association.destroy_all
end
distinct() Показать исходный код

Указывает, должны ли записи быть уникальными или нет.

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">]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 684
def distinct
  @association.distinct
end
Также известен как: uniq
empty?() Показать исходный код

Возвращает true, если коллекция пуста. Если коллекция загружена, это эквивалентно loaded? && empty?. Если коллекция не загружена, это эквивалентно !loaded?. Если коллекция еще не загружена, и вы собираетесь получить записи в любом случае, лучше проверить loaded?.

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
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 778
def empty?
  @association.empty?
end
fifth(*args) Показать исходный код

То же, что и first, за исключением того, что возвращается только пятая запись.

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 189
def fifth(*args)
  @association.fifth(*args)
end
find(*args, &block) Показать исходный код

Находит объект в коллекции, отвечающий условиям блока. Использует те же правила, что и select. Возвращает ошибку NoMethodError, если объект не найден.

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>
#    ]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 139
def find(*args, &block)
  @association.find(*args, &block)
end
first(*args) Показать исходный код

Возвращает первую запись или первые 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) # => []
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 169
def first(*args)
  @association.first(*args)
end
forty_two(*args) Показать исходный код

То же, что и first, за исключением того, что возвращается только сорок вторая запись. Также известен как доступ к «reddit».

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 195
def forty_two(*args)
  @association.forty_two(*args)
end
fourth(*args) Показать исходный код

То же, что и first, за исключением того, что возвращается только четвертая запись.

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 184
def fourth(*args)
  @association.fourth(*args)
end
include?(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
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 863
def include?(record)
  !!@association.include?(record)
end
last(*args) Показать исходный код

Возвращает последнюю запись или последние 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) # => []
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 225
def last(*args)
  @association.last(*args)
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>
#    ]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 756
def length
  @association.length
end
load_target() Показать исходный код
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 43
def load_target
  @association.load_target
end
loaded?() Показать исходный код

Возвращает true, если ассоциация загружена, в противном случае false.

person.pets.loaded? # => false
person.pets
person.pets.loaded? # => true
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 52
def loaded?
  @association.loaded?
end
many?(&block) Показать исходный код

Возвращает true, если коллекция содержит более одной записи. Эквивалентно length > 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

Вы также можете передать блок для определения критериев. Поведение такое же, он возвращает 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
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 849
def many?(&block)
  @association.many?(&block)
end
new(attributes = {}, &block)
Псевдоним для: build
prepend(*args) Показать исходный код
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 981
def prepend(*args)
  raise NoMethodError, "prepend on association is not defined. Please use << or append"
end
proxy_association() Показать исходный код
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 871
def proxy_association
  @association
end
push(*records)
Псевдоним для: <<
reload() Показать исходный код

Перезагружает коллекцию из базы данных. Возвращает self.

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1011
def reload
  proxy_association.reload
  self
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>]

Если предоставленный массив имеет неправильный тип ассоциации, он вызывает ошибку ArgumentError:

person.pets.replace(["doo", "ggie", "gaga"])
# => ActiveRecord::AssociationTypeMismatch: Pet expected, got String
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 358
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>]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1032
def reset
  proxy_association.reset
  proxy_association.reset_scope
  self
end
scope() Показать исходный код

Возвращает объект ActiveRecord::Scope для записей в этой ассоциации

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 884
def scope
  @association.scope
end
Также имеет псевдоним: spawn
scoping() { || ... } Показать исходный код

Мы не хотим, чтобы этот объект помещался в стек областей видимости, поскольку это может создать бесконечный цикл, в котором мы вызываем метод @association, который получает текущую область видимости, которая является этим объектом, который делегирует @association и так далее.

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 879
def scoping
  @association.scope.scoping { yield }
end
second(*args) Показать исходный код

То же, что и first, за исключением того, что возвращается только вторая запись.

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 174
def second(*args)
  @association.second(*args)
end
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

Во-вторых: Вы можете передать блок, чтобы использовать его так же, как Array#select. Это создаёт массив объектов из базы данных для области видимости, преобразуя их в массив и итерируясь по ним с помощью Array#select.

person.pets.select { |pet| pet.name =~ /oo/ }
# => [
#      #<Pet id: 2, name: "Spook", person_id: 1>,
#      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
#    ]

person.pets.select(:name) { |pet| pet.name =~ /oo/ }
# => [
#      #<Pet id: 2, name: "Spook">,
#      #<Pet id: 3, name: "Choo-Choo">
#    ]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 109
def select(*fields, &block)
  @association.select(*fields, &block)
end
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.
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 732
def size
  @association.size
end
spawn()
Псевдоним для: scope
take(n = nil) Показать исходный код
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 229
def take(n = nil)
  @association.take(n)
end
target() Показать исходный код
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 39
def target
  @association.target
end
third(*args) Показать исходный код

То же, что и first, но возвращает только третью запись.

# File activerecord/lib/active_record/associations/collection_proxy.rb, line 179
def third(*args)
  @association.third(*args)
end
to_a()
Псевдоним для: to_ary
to_ary() Показать исходный код

Возвращает новый массив объектов из коллекции. Если коллекция ещё не загружена, данные извлекаются из базы данных.

class Person < ActiveRecord::Base
  has_many :pets
end

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>
#    ]

other_pets = person.pets.to_ary
# => [
#       #<Pet id: 4, name: "Benny", person_id: 1>,
#       #<Pet id: 5, name: "Brain", person_id: 1>,
#       #<Pet id: 6, name: "Boss",  person_id: 1>
#    ]

other_pets.replace([Pet.new(name: 'BooGoo')])

other_pets
# => [#<Pet id: nil, name: "BooGoo", person_id: 1>]

person.pets
# This is not affected by replace
# => [
#       #<Pet id: 4, name: "Benny", person_id: 1>,
#       #<Pet id: 5, name: "Brain", person_id: 1>,
#       #<Pet id: 6, name: "Boss",  person_id: 1>
#    ]
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 950
def to_ary
  load_target.dup
end
Также псевдоним для: to_a
uniq()
Псевдоним для: distinct

© 2004–2016 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API