Моделі (Практика) | Ruby on Rails

Практичне завдання до теми в Моделі
Давайте розберем покрокове рішення нашого завдання.
- Створити модель Question(title, body) та Answer(content).
- Питання може мати декілька відповідей, а відповідь повинна належати тільки одному питанню.
- Кількість символів у заголовку та детальному описі питання не повинна бути менше 35.
- Кількість символів у відповіді на запитання не повинна бути менше 50. Усі поля повинні бути присутніми.
- Реалізувати колбек, який буде після збереження відповіді на запитання в базу данних перевіряти content на вміст нецензурних слів (наприклад: недоумок та дурак) та замінювати їх на «***».
Перший крок (створення моделей)
Першим кроком у роботі з моделлю в Rails є її створення. Для цього
використовується генератор командного рядка:
rails generate model Question
Після цього ми переходимо в проект, у нашу папку db/migrate/. Відкриваємо наш
файл з міграцією, де напишемо, які поля ми хочемо щоб були у нашого запитання.
class CreateQuestions < ActiveRecord::Migration[7.0] def change create_table :questions do |t| t.string :title t.text :body t.references t.timestamps end endend
- title: Заголовок питання, який містить текст питання або опис проблеми.
- body: Опис або текст питання більш детально.
Після створення моделі нам потрібно запустити міграцію спеціальною командою, щоб створити відповідну таблицю в базі даних:
rake db:migrate
Повторимо аналогічні дії, але тепер для моделі Answer з іншими полями.
class CreateAnswers < ActiveRecord::Migration[7.0] def change create_table :answers do |t| t.text :content t.references :question, foreign_key: true t.timestamps end endend
- content: Відповідь на питання, яка містить текст розв'язку або опис вирішення проблеми.
У Ruby on Rails ключове слово references використовується в контексті міграцій для визначення зв'язку з іншою моделлю. Коли ви використовуєте references в міграції, воно автоматично створює стовпець у таблиці бази даних для представлення зв'язку з іншою моделлю і встановлює зовнішній ключ для цього стовпця.
Другий крок (зв'язки між моделями)
Давайте тепер встановимо наш зв'язок за допомогою методу has_many в одній
моделі та методу belongs_to в іншій:
class Answer < ApplicationRecord belongs_to :questionendclass Question < ApplicationRecord has_many :answersend
По логіці зрозуміло, що питання може мати декілька відповідей, а відповідь може
належати одному питанню. Ми ж не можемо сказати, що відповідь підходить до
декількох питань, тому і використовуємо зв'язок "один до багатьох".
Третій крок (валідації)
Важливо додати валідацію до моделі, щоб перевірити правильність введених даних перед збереженням їх у базі даних. Наприклад, ви можете перевірити, чи поле не є порожнім та за умовою завдання кількість символів у полях (Question модель) не менше 35:
validates :title, presence: true, length: { minimum: 35 }validates :body, presence: true, length: { minimum: 35 }
Валідація для моделі Answer:
validates :content, presence: true, length: { minimum: 50 }
Четвертий крок (callback)
Давайте тепер використаєм колбек after_save, що виконується після збереження моделі:
class Answer < ApplicationRecord after_save :sanitize_content belongs_to :question validates :content, presence: true, length: { minimum: 35 } private def sanitize_content self.content = filter_text(self.content) self.save if self.changed? end def filter_text(text) forbidden_words = %w[недоумок дурак] forbidden_words.each do |word| text = text.gsub(/\b#{word}\b/i, '***') end text endend
Ми створили метод sanitize_content, в якому оновлюємо вміст нашої відповіді. Також у нас є ще один метод filter_text(), який виконується в методі sanitize_content. Це зроблено для кращої читабельноності коду. В цьому методі ми виконуєм логіку, яка замінює наші "нецензурні слова" на "***". Після того ми зберігаємо вміст (self.save) при перевірці, що ми хоть якось змінювали нашу відповідь - self.changed?.
Висновок
Отож, це одне з рішень нашої задачі, можливо ви вирішили її іншими способами, якщо ви знаєте як краще реалізувати певні пункти нашого завдання, то пишіть у коментарі.
