Запрос к БД можно осуществлять несколькими способами.
Пример. Сцепить несколько методов
Order.where("amount > 20").minimum(:amount)
# Вернет одно значение
Order.group(:state).maximum(:amount)
# Вернет хеш
Code language: Ruby (ruby)
Определить, доступны ли определенные атрибуты для этой модели.
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"]
false
Code 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.save
Code 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, если вы хотите убедиться, что ваша база данных согласована в соответствии с бизнес-правилами, определенными в ваших классах модели.