Рубрики
Agile Web Development with Rails 6 DB and Active Record Ruby on Rails Книги Программирование

Запросы к БД

Запрос к БД можно осуществлять несколькими способами.
Пример. Сцепить несколько методов

Order.where("amount > 20").minimum(:amount)
# Вернет одно значение

Order.group(:state).maximum(:amount)
# Вернет хешCode language: Ruby (ruby)

«.desc»

Сделает порядок по убыванию

«.order» и «.limit»

Можно вызывать только один раз в цепочке запроса

«.find_by_sql( ‘треб. к’ + ‘поиску’ )»

Создание «трудных» запросов к БД

Определить, доступны ли определенные атрибуты для этой модели.

attribute_names, attribute_present?

orders = Order.find_by_sql("select name, pay_type from orders")

first = orders[0]
p first.attributes
p first.attribute_names
p first.attribute_present?("address")Code language: Ruby (ruby)

Этот код вернет

{"name"=>"Dave Thomas", "pay_type"=>"check"}
["name", "pay_type"]
falseCode language: Ruby (ruby)

В запросе «.find_by_sql» мы можем задавать псевдонимы с пометкой «as»

items = LineItem.find_by_sql(
"select *, " + " products.price as unit_price, " +
" quantity*products.price as total_price, " + 
" products.title as title " +
" from line_items, products" +
" where line_items.product_id = products.id ")

puts "#{li.title}: #{li.quantity}x#{li.unit_price} => #{li.total_price}"
Code language: Ruby (ruby)

«.find_by_sql» — может принимать массив, где первое значение строка содержащая placeholder, вторая часть хеш или список значений для замены


Обновление существующих строк

С помощью .save

orders = Order.find_by_sql("select id, name, pay_type from orders where id=123")
first = orders[0]
first.name = "Wilma"
first.saveCode language: Ruby (ruby)

C помощью .update. Использовать .save не нужно

order = Order.find(321)
order.update(name: "Barney", email: "barney@bedrock.com")Code language: JavaScript (javascript)

Наконец, метод класса update_all позволяет нам указать предложения set и where оператора обновления SQL. Например, следующее увеличивает цены на все продукты, в названии которых есть Java, на 10 процентов:

 result = Product.update_all("price = 1.1*price", "title like '%Java%'")Code language: Ruby (ruby)

Возвращаемое значение update_all зависит от адаптера базы данных; большинство (но не Oracle) возвращают количество строк, которые были изменены в базе данных.

save, save!, create, and create!

Оказывается, есть две версии методов save и create. Варианты различаются способом сообщения об ошибках.

  • save возвращает true, если запись была сохранена; в противном случае возвращается nil.
  • save! возвращает истину, если сохранение выполнено успешно; в противном случае возникает исключение.
  • create возвращает объект Active Record независимо от того, был ли он успешно сохранен. Вам нужно будет проверить объект на наличие ошибок проверки, если вы хотите определить, были ли данные записаны.
  • create! возвращает объект Active Record в случае успеха; в противном случае возникает исключение.

Удаление строк delete

delete — удаляем по id или по массиву id

delete_all — удаляем все или только те что мы определим

o.delete([2,3,4])
Product.delete_all(["price > ?", @expensive_price])Code language: Ruby (ruby)

destroy

Зачем нам нужны методы класса delete и destroy? Методы удаления обходят различные функции обратного вызова и проверки Active Record, в то время как методы уничтожения гарантируют, что все они будут вызваны. В общем, лучше использовать методы destroy, если вы хотите убедиться, что ваша база данных согласована в соответствии с бизнес-правилами, определенными в ваших классах модели.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *