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, и вы можете сосредоточиться на работе с данными в своем приложении.