Сейчас четвертая неделя в FS, и мы больше не новички в кампусе. В прошлую пятницу мы закончили наш первый модуль программы, изучая ActiveRecord и его важность для того, чтобы сделать нашу жизнь как веб-разработчиков менее безболезненной. Сегодня я напишу о нескольких методах ActiveRecord, которые могут даже сделать нашу карьеру программиста немного более приятной.

выщипывать (имя_столбца)

pluck можно использовать для запроса одного или нескольких столбцов из базовой таблицы модели. Он принимает в качестве аргумента список имен столбцов и возвращает массив значений указанных столбцов с соответствующим типом данных.

Pluck просто выберет нужные атрибуты и вернет их значения в виде массива.

Artist.pluck(:name)

можно увидеть так же, как:

Artist.all.map(&:name)

Оба запроса вернут значения атрибута имени для экземпляров класса Artist.

Artist.all
# => [#<Artist:0x007fc7f4e036e8 id: 1, name: "don mcclean">]
Artist.pluck(:name)
# SELECT "artists"."name" FROM "artists"
# => ["don mcclean"]
Artist.all.map(&:name)
# SELECT "artists".* FROM "artists"
# => ["don mcclean"]

Pluck также может использоваться с различными предложениями, такими как where и order.

Song.all
# =>
[#<Song:0x007fc7fb0a1c00 id: 1, name: "American Pie", artist_id: 1>, #<Song:0x007fc7fb0a1ac0 id: 3, name: "And I Love You So", artist_id: 1>, #<Song:0x007fc7fb0a1980 id: 2, name: "Vincent", artist_id: 1>]
Song.where(name: "Vincent").pluck(:id)
# SELECT "songs"."id" FROM "songs" WHERE "songs"."name" = ?
# => [2]
Song.order(:name).pluck(:id)
# SELECT "songs"."id" FROM "songs" ORDER BY "songs"."name" ASC
# => [1, 3, 2]

присутствовать? и пусто?

Объект является пустым, если он является ложным, пустым или представляет собой строку с пробелами. Например, false, '', ' ', nil, [] и {} пусты.

Объект присутствует, если он не пуст.

#пустой? можно близко назвать #empty? метод, который мы все знаем, но с несколькими исключениями:

  • #пусто? нельзя использовать для объекта, отличного от класса Hash, Array и String. #пусто? Метод можно использовать на любом объекте.
  • #пусто? метод вернет «Ошибка метода нет» при использовании для нулевого объекта. #пусто? метод вернет true, если значение равно nil, false, пустой или пробельной строке.

Давайте посмотрим на некоторые примеры использования #empty? и #пусто?

[].empty?
# => true
"   ".empty?
# => false
nil.empty?
# => NoMethodError
[].blank?
# => true
"   ".blank?
# => true
nil.blank?
# => true

Song.all
# =>
[#<Song:0x007fc7fb0a1c00 id: 1, name: "American Pie", artist_id: 1>, #<Song:0x007fc7fb0a1ac0 id: 3, name: "And I Love You So", artist_id: 1>, #<Song:0x007fc7fb0a1980 id: 2, name: "Vincent", artist_id: 1>]
Song.all.first.empty?
# SELECT  "songs".* FROM "songs" ORDER BY "songs"."id" ASC LIMIT ?
# => NoMethodError: undefined method `empty?' for #<Song id: 1, name: "American Pie", artist_id: 1>
Song.all.first.blank?
# SELECT  "songs".* FROM "songs" ORDER BY "songs"."id" ASC LIMIT ?
# => false

Здорово! Теперь, что #представляет? делать?
#подарок? метод является полной противоположностью #blank?.

[].present?
# => false
"   ".present?
# => false
nil.present?
# => false

Song.all.first.present?
# SELECT  "songs".* FROM "songs" ORDER BY "songs"."id" ASC LIMIT ?
# => true

область действия (имя, текст и блок)

Добавляет метод класса для получения и запроса объектов. Метод предназначен для возврата объекта ActiveRecord::Relation, который компонуется с другими скоупами. Если он возвращает nil или false, вместо этого возвращается область действия все.

Проще говоря, области действия почти такие же, как и методы класса.

class Shirt < ActiveRecord::Base
  def self.shirt_color(color)
    self.where(name: color)
  end
  
  # This is the same as:
  scope :shirt_color, -> color { where(name: color) }
end

Если бы мы вызвали Shirt.shirt_color(color), возвращаемое значение было бы одинаковым для обоих случаев.

Shirt.all
# => [#<Shirt:0x007fbc120afb60 id: 1, name: "black">,
#     #<Shirt:0x007fbc120ac168 id: 2, name: "white">]
scope :shirt_color, -> color { where(name: color) }
Shirt.shirt_color('black')
# SELECT "shirts".* FROM "shirts" WHERE "shirts"."name" = ?
# => [#<Shirt:0x007fc0ad8516a8 id: 1, name: "black">]


def self.shirt_color(color)
  self.where(name: color)
end
Shirt.shirt_color('black')
# SELECT "shirts".* FROM "shirts" WHERE "shirts"."name" = ?
# => [#<Shirt:0x007fa924800de8 id: 1, name: "black">]

Так в чем же разница между использованием Scope и использованием метода класса?

Разница между областью действия и методом класса заключается в том, что область действия всегдавозвращает отношение (т. е. запрос self.all), тогда как класс метод не будет, если мы явно не укажем ему. Эта функция позволяет всегда связывать метод области, поэтому он не сломается, даже если в качестве аргумента будет передано значение nil или false.

Давайте возьмем наш предыдущий пример и попробуем реализовать настоящий? и выщипывать методы в нашей области видимости и методах класса.

class Shirt < ActiveRecord::Base
  scope :shirt_color, -> color { where(name: color) if    color.present? }
  def self.shirt_color(color)
    self.where(name: color) if color.present?
  end
end

Если бы мы дали методу нашего класса аргумент nil, что бы произошло?

Shirt.shirt_color(nil)
# => nil
Shirt.shirt_color(nil).pluck(:name)
# => NoMethodError: undefined method `pluck' for nil:NilClass

Наш метод класса по умолчанию возвращает значение nil, так как наш «if color.present?» утверждение оказывается ложным. Методу не удается найти совпадение для nil, что, в свою очередь, приводит к ошибке при вызове #pluck.

Теперь давайте попробуем сделать то же самое с нашим методом области видимости.

Shirt.shirt_color(nil)
# SELECT "shirts".* FROM "shirts"
# => [#<Shirt:0x007feb8cd06108 id: 1, name: "black">,
#    #<Shirt:0x007feb8cd05fc8 id: 2, name: "white">]

Shirt.shirt_color(nil).pluck(:name)
# SELECT "shirts"."name" FROM "shirts"
# => ["black", "white"]

Мы видим, что наш метод области действия возвращает все экземпляры класса Shirt, поскольку он не смог найти совпадение для заданного аргумента nil. Но поскольку метод области видимости возвращал все экземпляры класса Shirt, мы все еще могли продолжать цепочку нашего метода #pluck, который в конечном итоге возвращал нам все названия цвета рубашки.

Итак, в целом мы рассмотрели только три метода из многих, которые предоставляет нам ActiveRecord, и мы уже видим, насколько мощным он может быть. Обязательно будет много более полезных и мощных методов, с которыми мы еще не знакомы, так что давайте продолжим исследовать и экспериментировать!

Источники