Настало время для работы с SQL прямо из Ruby кода. Для того, чтобы это было возможно, необходимо установить библиотеку sequel
gem 'sequel','~> 5.69'
Также СУБД бывают различные и каждая из СУБД предоставляет свой собственный API для различных языков программирования. В Ruby для работы с SQLite необходим дополнительный гем
Теперь мы можем получить доступ до Sequel в нашем коде.
Для того, чтобы начать посылать запросы, нам нужно установить соединение с базой данных:
require'sequel'DB=Sequel.connect('sqlite://shop.db') # указываем путь до файла БД относительно .rb файла# Также можно использовать именованные параметры на основе Hash. В данном случае необходимо обязательно укзаать значение для adapter# DB = Sequel.connect(adapter: :sqlite, user: 'user', password: 'password', host: 'host', port: port, database: 'database_name.db')
DDL операции
Sequel предоставляет нам удобный DSL (domain-specific language) для выполнения DDL операций. Например, так будет выглядеть операция для создания таблицы items:
# В качестве аргумента передает название таблицы в виде символа, а также блок кодаDB.create_table:itemsdo primary_key :id# внутри которого с помощью методов описываем нашу таблицу column :manufacture,String,null:false column :model,String,null:false column :color,String,null:false column :price,Integernull:false, column :date_added,Time,null:falseend
В данном примере мы вызывали метод .column в который передавали:
название колонки
класс Ruby, который имеет сопоставление с типами SQL
параметры, передаваемые в виде хэша
DML операции
После того как таблица создана, рассмотрим пример запроса для получения товаров стоимостью выше 10 000 рублей отсортированные по цене в порядке убиывания
Мы можем также добавлять значения в нашу таблицу:
Точно также как и удалять:
Sequel как ORM
Чаще всего встречается использование ORM для работы с базой данных. ORM - Object Relational Mapping. По сути, это работа с таблицами как с Ruby объектами, где каждый атрибут объекта - атрибут таблицы. Давайте создадим такой класс для нашей таблицы items.
Важно при этом создать объект соединения с помощью Sequel.connect(...), так как при создании модели будет использоваться неявно(без использования переменной) ранее созданное соеднинение. Сначала создаем соединение, потом инициализируем модели с помощью require.
Ассоциации
Кроме того, в моделях нам доступны ассоциации. Ассоциации позволяют одной модели ссылаться на другие в случае, если между ними есть связь в виде FK.
Рассмотрим основные связи:
many_to_one - ассоциация описывает отношение "многие к одному" между двумя таблицами в базе данных. Это означает, что одна запись в "родительской" таблице может быть связана с множеством записей в "дочерней" таблице, но каждая запись "дочерней" таблицы имеет связь только с одной записью из "родительской" таблицы.
Пример использования ассоциации many_to_one для двух таблиц: students и classrooms. Здесь один класс (classroom) может иметь много студентов (students), но каждый студент может быть только в одном классе.
Структура двух таблиц:
students
id
name
classroom_id
1
Alice
1
2
Bob
1
classrooms
id
name
1
Math Class
Объявление моделей с ассоциацией в Sequel:
Теперь вы можете получить класс (classroom) каждого студента с помощью ассоциации many_to_one:
В данном случае, ассоциация many_to_one позволила установить связь между таблицами таким образом, что для каждого объекта Student можно легко получить соответствующий объект Classroom, без необходимости писать дополнительные SQL-запросы.
one_to_many - ассоциация описывает отношение "многие ко многим" между двумя таблицами в базе данных. Это означает, что одна запись в первой таблице может быть связана с несколькими записями во второй таблице, и наоборот, одна запись во второй таблице может быть связана с несколькими записями в первой таблице.
Для реализации такого отношения обычно используется третья таблица, называемая "связующей" (join) таблицей, которая содержит внешние ключи (foreign keys) для обеих таблиц и связывает их записи.
Пример использования ассоциации many_to_many для таблиц students, courses, и связующей таблицы enrollments. Здесь один студент может быть записан на несколько курсов, и каждый курс может иметь несколько студентов.
Структура таблиц:
students
id
name
1
Alice
courses
id
name
1
Math
2
History
enrollments
student_id
course_id
1
1
1
2
Объявление моделей с ассоциацией в Sequel:
Теперь вы можете получить все курсы, на которые записан студент, или все студенты, которые записаны на курс, с помощью ассоциации many_to_many:
Таким образом, ассоциация many_to_many позволяет установить связь многие ко многим между двумя таблицами с использованием связующей таблицы, и предоставляет удобный способ получения и работы с этими связями на уровне объектов Ruby и моделей Sequel.
Обратите внимание на следующие правила и рекомендации по составлению названий таблиц, классов и ассоциаций в контексте таблиц базы данных и объектно-реляционного отображения, такого как Sequel:
Таблицы:
Обычно названия таблиц должны быть во множественном числе и в нижнем регистре (например, students, bo`oks).
Используйте подчеркивания для разделения слов в названиях таблиц (например, book_authors, order_items).
Старайтесь делать названия короткими и ясными, чтобы они отражали назначение таблицы.
Классы и модели:
Имена классов и моделей должны быть в единственном числе и в формате CamelCase (например, Student, Book).
Каждое слово в имени класса должно начинаться с заглавной буквы и не содержать подчеркиваний (например, BookAuthor, OrderItem).
Ассоциации:
Названия ассоциаций one_to_many и many_to_many должны быть во множественном числе и в нижнем регистре, чтобы они соответствовали названиям таблиц (например, students, books).
Названия ассоциации many_to_one должно быть в единственном числе и в нижнем регистре, чтобы оно соответствовали названию класса и модели в нижнем регистре (например, student, book).
В случае если названия классов или ассоциаций отличаются от названий таблиц или не выполняют какое-либо из выше перечисленных правил, то необходимо будет вручную проставлять нзавания классов/таблиц. В противном случае работать это не будет.
Задание university
Задание todo_api
Напишите используя Sinatra и Sequel приложение для работы со списком дел, которое:
Добавляет новое дело в базу данных
Изменяет дело по его идентификатору
Удаляет дело по его идентификатору
Показывает список дел постранично
Рекомендации:
Требований как должна выглядеть модель дела здесь нет, поэтому можете включить свою фантазию и придумать
Для того, чтобы модель Sequel могла бы быть преобразована в JSON, вам необходимо включить JSON сериализацию
table = DB[:items]
result = table
.where{price > 10_000} # создаем блок кода с передачей условия в него
.order(Sequel.desc(:price)) # вызываем метод для сортировки
p result # Получаем массив значений в виде хэша
require 'sequel'
# Sequel обязывает нас называть наши классы как таблицы в единственном числе
# Он использует название класса для определния названия таблицы
# если нам нужно изменить это поведение,
# то необходимо наследоваться с использованием названия в качестве аргумента (Sequel::Model(:items))
class Item < Sequel::Model
end
Item.where{price > 10_000}.order(Sequel.desc(:price))
class Student < Sequel::Model
many_to_one :classroom
end
class Classroom < Sequel::Model
one_to_many :students
end
class Student < Sequel::Model
many_to_many :courses, join_table: :enrollments
end
class Course < Sequel::Model
many_to_many :students, join_table: :enrollments
end