Найкраща практика рейлів - збереження адреси в PostgreSQL

Розширення 'hstore' реалізує тип даних 'hstore' для зберігання наборів пар ключів / значень

Анотація: запропонуйте рішення, яке пропонує послідовний, ефективний та надійний метод зберігання та отримання складних типів даних із бази даних SQL.

Планування додатків є важливим і часто не поміченим кроком у створенні успішних веб-додатків. Рамкова система Rails дозволяє настільки легко створити та завантажувати додаток, що розробникам спокусити пропустити планування та перейти до розробки. Однак генерація коду програми перед правильним плануванням домену може призвести до неохайних або навіть неправильних програм. Розглянемо, наприклад, найкращий метод обробки поля "адреса" в додатку.

Що за адреса?

Ось як виглядає типова адреса в США:

Адреса: [
Вулиця: Рядок "123 День щасливих днів"
Місто: Рядок "Країна чудес"
Держава: Рядок "ПА"
Zip: 10102 Рядок
]

Значення "Адреса" складається з масиву пар ключів / значень, де значенням є рядок. Це дуже поширене поле в програмах. Отже, який найкращий спосіб представити значення "Адреса" в базі даних SQL? Щоб зрозуміти це, давайте подивимось, що роблять інші розробники в цій ситуації.

Варіант 1: Збережіть значення в одному полі як рядок, наприклад:

Адреса: “123 Ln Happy Days Ln Країна чудес, Пенсільванія 10102 ”

Це невдале рішення. Як ми бачили у розділі вище, адреса - це масив пар ключ / значення. Трактувати адресу, як і будь-яке інше скалярне поле, було б непослідовно. Ця невідповідність стає очевидною, коли ми хочемо розширити програму в якийсь момент майбутнього. Скажімо, ми хочемо знайти всіх клієнтів із певного "міста" чи "штату". Оскільки ціле значення "Адреса" було введено в рядок, це вже не є простим способом.

Варіант 2: Розбийте значення "Адреса" на окремі поля та збережіть ці поля, наприклад:

Вулиця: “123 Ln Happy Days Ln”, Місто: “Wonderland”, Штат: “PA”, Поштовий індекс: “10102”

Тут ми вирішили попереднє гіпотетичне розширення пошуку всіх клієнтів певного «міста» чи «держави». Однак ми зараз представляємо поле "Адреса" чотирма окремими і різними полями, коли насправді поля повинні бути об'єднані разом.

Варіант 3: Створіть окрему таблицю адрес та асоціацію іноземних ключів

Кілька публікацій блогів та відповідей StackOverflow приходять до висновку, що найкращим способом зберігання адрес у Rails є використання окремої моделі та асоціації last_to. Таким чином, модель користувача або бізнесу може мати_мало адрес і не обмежуватися однією адресою. Також адреси будуть правильно зберігатися, оскільки кожна модель "Адреса" буде складатися з її ключів та відповідних значень. Це не є поганим рішенням, якщо припустити, що ваша додаткова модель, наприклад, "Користувачі", вимагає отримання кількох адрес. Однак якщо для кожної моделі потрібна лише одна адреса (як це стосується більшості людей, поштова адреса), додаючи додаткові таблиці та асоціації, ви без потреби збільшуєте складність програми. Генерувати таблиці та асоціації в Rails досить просто, що, ймовірно, є причиною цього третього варіанту. Створити нову таблицю "Адреса" з відповідною асоціацією з "Користувачем" так само просто, як: rails g модель Адреса вулиця: місто рядка: string string: string zip: string user: reference Тоді виникає питання: "це найкраще Практика для вашої заявки, чи це просте рішення більш складного питання? "

Рішення:

Rails / PostgreSQL - це загальний стек технологій, що використовується при розробці та виробництві. Існує спосіб зберігання адрес у їх правильній формі, включивши розширення 'hstore'. Це розширення дозволяє нам зберігати дані як тип "hstore" (хеш-магазин). Перший крок - включити модуль 'hstore'. Для цього ми напишемо міграцію:

Коли ми запустимо команду "rails db: migrate" з командного рядка, Postgres увімкне розширення "hstore". Це можна перевірити, перевіривши файл schema.rb. Зараз у верхній частині файлу ви повинні побачити:

 # Це розширення, які потрібно ввімкнути для підтримки цієї бази даних
enable_extension “plpgsql”
enable_extension “hstore”

Далі ми створимо міграцію для моделі користувача:

Зверніть увагу, як ми використовуємо тип даних "hstore" для адресного поля. Це дозволяє нам зберігати пари ключів / значень у межах "адреси".

Убік: поле "hstore" може використовуватися для зберігання будь-яких пар ключів / значень. У цій статті ми вивчаємо "Адреса", але це так само корисно для зберігання "Налаштування" або будь-якого іншого типу даних хешу.

Отже, тепер у нас є єдине поле, яке, як ми знаємо, може зберігати дані у вигляді, City => "Wonderland" та State => "PA". Ми можемо створити модель "Користувач" та контролер "Користувачі", але як ми насправді зберігаємо пари ключів / значень в одному полі бази даних? Є ще один розгляд, який можна зробити, як ми можемо зберегти пару ключів / значень City => «Країна чудес» до поля «адреса»?

З точки зору контролера, ми повинні спочатку додати білий список усіх параметрів, перш ніж вони можуть бути присвоєні масі. Це робиться в приватному методі "user_params", так само, як і в будь-якому іншому полі бази даних.

За допомогою білого списку того, що можна призначити за адресою, ми надали конкретні вказівки щодо даних, які ми очікуємо. Поле адреси може мати пару міста / значення або пару стану / значення, але не пара мавп / значення.

У нашій формі користувача ми надаємо відповідні поля для збору даних:

Вся форма показана для демонстрації. Однак початок і кінець адресного поля позначені html-коментарями. Зверніть увагу, як ми використовуємо помічник форми для створення полів для адреси. Кожне поле відповідає параметру білого списку, який ми вказали в контролері. Хоча це не стосується цієї статті, форма стилізована до класів із бібліотеки Semantic-UI - це означає, що вона буде чуйною і виглядає приголомшливо!

Вище відображається форма в браузері

Ми можемо швидко створити користувача та побачити, як виглядає поле "Адреса":

Поле адреси зберігається як хеш пар ключів / значень, ідеально!

На зображенні вище, термін "суб'єкт" є синонімом "користувач". Як ви бачите, поле "Адреса" зберегло наші пари ключів / значень від контролера так, як ми очікували. Якщо ми хочемо знайти значення міста конкретного користувача, яке ми можемо використовувати, @ user.address ['city'], і це поверне «Wonderland» у нашому прикладі використання.

У цій статті ми відкрили оптимальний метод збереження та запиту складних типів даних у PostgreSQL за допомогою розширення 'hstore'. Ми визначили, що як найкраща практика першими кроками у створенні веб-програми є планування та збір інформації. Ми також дізналися цінність відкриття інформації самі, досліджуючи та читаючи документацію. Тільки тому, що інший розробник чи компанія робить щось в один бік, це не означає, що нам слід сліпо слідувати. Важливо ставити під питання «чому» і використовувати власні пізнавальні здібності для логічного висновку. Сподіваюся, ви знайшли цю статтю корисною. Для отримання додаткової інформації та навчальних посібників з веб-технологій відвідайте Learn2Code.