Ruby позволяет нам создавать сложные наборы данных, требующие связи между данными.

Любой веб-сайт, которому требуется больше, чем просто статическая информация в блоге, требует динамической архитектуры, чтобы конечные пользователи могли беспрепятственно взаимодействовать с вашим сайтом без постоянных перезагрузок. Вспомните Google Docs или Twitter.com, этим приложениям требуются динамические пользовательские функции, но, что более важно, требуется база данных информации на серверной части для сохранения конкретных сведений о пользователе. Хотя эти веб-приложения по-прежнему можно кодировать во внешнем интерфейсе с использованием базовых HTML, CSS и JavaScript, разработчикам требуется больше инструментов для работы со сложными пользовательскими данными. В мире, где используется только Javascript, у разработчиков есть только простые инструменты для баз данных, такие как MongoDB — формат базы данных NoSQL, который не допускает взаимосвязей между вашими данными.

Представьте Ruby… объектно-ориентированный язык программирования, который позволяет разработчикам писать внутренний код с использованием реляционных баз данных или, другими словами, баз данных SQL, таких как MySQL, PostgreSQL и SQLite.

Хотя Ruby известен своими преимуществами в плане читабельности и масштабируемости, мы сосредоточимся на том, что он позволяет использовать базы данных на основе отношений. Представьте SQL… язык программирования, используемый для управления реляционными базами данных. Мы используем его для извлечения, обработки и хранения данных, и он широко используется в корпоративных приложениях для управления большими объемами структурированных данных. Мы можем писать запросы и операторы для извлечения, вставки, обновления и удаления наших данных.

Давайте подумаем о веб-сайте бронирования ресторанов. У ресторана много заказов и клиентов. Посетители имеют много разных оговорок.

Чтобы создать эту базу данных и сопоставить различные данные друг с другом, требуется много ручного написания SQL…

require 'sqlite3'

# Connect to the database
db = SQLite3::Database.new 'restaurant_reservations.db'

# Create the restaurant table
db.execute <<-SQL
  CREATE TABLE IF NOT EXISTS restaurants (
    id INTEGER PRIMARY KEY,
    name TEXT,
    address TEXT,
    phone TEXT
  );
SQL

# Create the customer table
db.execute <<-SQL
  CREATE TABLE IF NOT EXISTS customers (
    id INTEGER PRIMARY KEY,
    name TEXT,
    phone TEXT,
    email TEXT
  );
SQL

# Create the reservation table
db.execute <<-SQL
  CREATE TABLE IF NOT EXISTS reservations (
    id INTEGER PRIMARY KEY,
    restaurant_id INTEGER,
    customer_id INTEGER,
    date TEXT,
    time TEXT,
    party_size INTEGER,
    FOREIGN KEY (restaurant_id) REFERENCES restaurants(id),
    FOREIGN KEY (customer_id) REFERENCES customers(id)
  );
SQL

Теперь, когда таблицы созданы, для создания, чтения, обновления или удаления данных нам нужно написать длинные операторы SQL, подобные этому:

# Insert a restaurant
db.execute("INSERT INTO restaurants (name, address, phone) VALUES ('The Cheesy Bistro', '123 Main St', '555-555-5555');")

# Insert a customer
db.execute("INSERT INTO customers (name, phone, email) VALUES ('John Doe', '555-555-5556', '[email protected]');")

# Insert a reservation
db.execute("INSERT INTO reservations (restaurant_id, customer_id, date, time, party_size) VALUES (1, 1, '2023-02-12', '7:00 PM', 4);")

Active Record облегчает жизнь рубистам

Хотя в Ruby есть библиотеки и инструменты для доступа к реляционным базам данных, таким как MySQL, Microsoft SQL Server и Oracle, и управления ими, существует более новая среда Ruby, упрощающая взаимодействие с данными. Представляем Active Record… Active Record — это драгоценный камень Ruby, который добавляется в виде упакованной библиотеки поверх вашей существующей программы Ruby.

Как часть Ruby on Rails, Active Record обеспечивает объектно-реляционное сопоставление (ORM). Этот уровень ORM находится поверх SQL и позволяет нам использовать объекты и методы Ruby вместо написания необработанных операторов SQL. Давайте снова возьмем пример с рестораном и покажем, как легко использовать Active Record для создания отношений. Имейте в виду, что нам все еще нужен SQLite.

require 'sqlite3'
require 'active_record'

# Connect to the database
ActiveRecord::Base.establish_connection(
  adapter: 'sqlite3',
  database: 'restaurant_reservations.db'
)

# Define the restaurant model
class Restaurant < ActiveRecord::Base
  has_many :reservations
  has_many :customers, through: :reservations
end

# Define the customer model
class Customer < ActiveRecord::Base
  has_many :reservations
  has_many :restaurants, through: :reservations
end

# Define the reservation model
class Reservation < ActiveRecord::Base
  belongs_to :restaurant
  belongs_to :customer
end

# Create the restaurant table
ActiveRecord::Schema.define do
  create_table :restaurants do |t|
    t.string :name
    t.string :address
    t.string :phone
  end

  create_table :customers do |t|
    t.string :name
    t.string :phone
    t.string :email
  end

  create_table :reservations do |t|
    t.belongs_to :restaurant, index: true
    t.belongs_to :customer, index: true
    t.date :date
    t.time :time
    t.integer :party_size
  end
end

Теперь для создания данных в нашей базе данных мы используем синтаксис Active Record:

# Insert a restaurant
restaurant = Restaurant.create(name: 'The Cheesy Bistro', address: '123 Main St', phone: '555-555-5555')

# Insert a customer
customer = Customer.create(name: 'John Doe', phone: '555-555-5556', email: '[email protected]')

# Insert a reservation
reservation = Reservation.create(restaurant: restaurant, customer: customer, date: '2023-02-12', time: '7:00 PM', party_size: 4)

Но реальная сила Active Record заключается в простоте написания простых действий CRUD (создание, чтение, обновление, удаление). Внезапное выполнение запросов и сложных действий — это просто вызов метода.

СОЗДАТЬ. С помощью Active Record вы можете создавать новые записи, просто создавая экземпляр модели и вызывая метод create. Метод автоматически вставляет данные в соответствующую таблицу.

# Insert a restaurant
restaurant = Restaurant.create(name: 'The Cheesy Bistro', address: '123 Main St', phone: '555-555-5555')

# Insert a customer
customer = Customer.create(name: 'John Doe', phone: '555-555-5556', email: '[email protected]')

# Insert a reservation
reservation = Reservation.create(restaurant: restaurant, customer: customer, date: '2023-02-12', time: '7:00 PM', party_size: 4)

READ — Active Record предоставляет различные методы для извлечения данных из базы данных, например all для извлечения всех записей, find для извлечения записи по идентификатору и reservations для извлечения всех резервирований для ресторана через ассоциацию.

# Find all restaurants
restaurants = Restaurant.all

# Find a customer by ID
customer = Customer.find(1)

# Find all reservations for a restaurant
reservations = restaurant.reservations

ОБНОВЛЕНИЕ. С помощью Active Record вы можете обновлять записи, просто вызывая метод update для экземпляра модели. Метод автоматически обновляет данные в соответствующей таблице.

# Update a restaurant
restaurant.update(name: 'The Cheesy Bistro 2.0')

# Update a customer
customer.update(email: '[email protected]')

УДАЛЕНИЕ. С помощью Active Record вы можете удалять записи, просто вызывая метод destroy для экземпляра модели. Метод автоматически удаляет данные из соответствующей таблицы.

# Delete a restaurant
restaurant.destroy

# Delete a customer
customer.destroy

Заключение

Как видите, Active Record делает выполнение действий CRUD намного проще и удобнее по сравнению с написанием простых операторов SQL. Вам не нужно беспокоиться о деталях написания и выполнения операторов SQL, и вы можете сосредоточиться на работе с данными в своем приложении.

Таким образом, Active Record обеспечивает несколько преимуществ по сравнению с использованием простого SQL: абстракция, простота использования, отношения и проверка.