Як оновити мій додаток до Rails 7

pic

Система до оновлення

  • Ruby 2.7.2 як основний інтерпретатор ruby
  • Rails 6.1 як фреймворк
  • Використання Sprockets для керування CSS та JavaScript
  • Bootstrap 5.1.3 як фронтенд-фреймворк
  • Resque для обробки фонних завдань
  • Rbenv як система керування версіями ruby
  • PostgreSQL як база даних
  • Puma + Nginx як веб-сервер
  • Ubuntu 20.04 як операційна система

Резервне копіювання та створення нової гілки git

  • У моїй розробницькій системі (Mac OS Big Sur) я роблю резервну копію папки з програмою, стискаючи її в zip файл
  • Створюю нову гілку git для оновлення
  • git checkout -b 51-new-branch-name
  • Використання нової гілки git, ймовірно, достатньо, але я хочу створити план B для резервної копії

Проблема з форматом дати

  • Всі системи, які я оновлював, використовують формат "dd-mm-yyyy", і зазвичай це вирішується централізовано за допомогою налаштувань у config/initializers/date_format.rb
# Формат за замовчуванням для відображення дат і часу  
Date::DATE_FORMATS[:default] = "%d-%m-%Y"  
Time::DATE_FORMATS[:default] = "%d-%m-%Y"
  • Це налаштування змінюється після оновлення до Rails 7. Якщо я не вказую формат дати явно, то формат дати повертається до стандартного формату Rails, який виглядає як "yyyy-mm-dd"
  • Тому я повинен перевірити і змінити кожен файл подання (.html.erb), який показує дату, і чесно кажучи, це найбільш тривалий процес, оскільки я маю перевірити кожен файл подання

Проблема з Date.today, це буде показувати "yyyy-mm-dd" за замовчуванням

  • Є 2 рішення цієї проблеми:
  • рішення 1: додати формат безпосередньо: Date.today.strftime(“%d-%m-%Y”)
  • рішення 2: створити допоміжну функцію в App/helpers/application_helper.rb (рекомендовано, оскільки це чистіше)
def today_date  
 Date.today.strftime("%d-%m-%Y")  
end
  • у ваших файлах подання викликайте функцію
<%= text_field_tag :end_date, today_date , :class => 'form-control datepicker' %>

Проблема з полем введення, яке показує дату

  • ми додали значення: f.object.end_date&.strftime(“%d-%m-%Y”), це означає, що ми використовуємо попереднє значення, якщо воно існує, і форматуємо його за допомогою strftime
<%= f.text_field :end_date, value: f.object.end_date&.strftime("%d-%m-%Y"), class: 'form-control datepicker', :required => true %>

Пошук за допомогою Ransack, який шукає записи за період дат

  • Ось код нижче для збереження попередніх значень параметрів, що дозволить відображати дату з постійним форматом після того, як користувач натисне кнопку пошуку

Оператор render

Перевірка всередині контролерів та подань

  • Видалити розширення файлів при виклику файлів за допомогою render
  • наприклад: <%= render ‘absens/list/export.html.erb’ %>
  • видаліть .html.erb на <%= render ‘absens/list/export’ %>

Ви можете використовувати допоміжні засоби для свого редактора, наприклад, якщо я використовую Sublime,

  • Я використовую cmd+shift+f для пошуку і заміни і шукаю .html.erb, а потім заміняю на без розширення,
  • потім ви можете використати меню Файл, Зберегти всі, щоб зберегти всі замінені документи,
  • потім можна використати меню Файл, Закрити всі файли, щоб закрити всі
  • ось розширення, які я використовую і замінив на без розширення ( .html.erb, .xls.erb, .xlsx.axlsx, .js.erb )

Рендеринг xls файлу

  • Якщо ви досі рендерите xls файл, ось кілька команд, які працюють (зазвичай це знаходиться у вашому контролері)

Рендеринг xlsx файлу

  • якщо ви рендерите xlsx файл, раніше я використовував render file:, а зараз потрібно використовувати render xlsx:

Використання Redis замість інших

  • Раніше я використовував gem hiredis і виникали проблеми після оновлення
  • Щоб вирішити цю проблему, я видалив hiredis і redis-rails та додав redis у Gemfile
  • Переконайтеся, що якщо ви використовуєте hiredis, видаляєте ініціалізуючий файл у /config/initializers/redis.rb

Заміна оператора image open(url) на image URI.open(url)

  • оскільки я також оновив ruby з версії 2.7.2 до 3.0.3, оператор image open(url) депрецьований у ruby 3, тому я змінив на image URI.open
  • використовуючи Sublime, я допомагаю знайти image open і замінити на image URI.open

Резервне копіювання важливих налаштувань

Ці важливі кроки, переконайтеся, що ви зробили резервну копію таких файлів нижче, оскільки скрипт оновлення rails 7 перезаписує ці файли, і ви втратите деякі важливі налаштування в цих файлах.

Ось файли для резервного копіювання:

  • config/boot.rb
  • config/application.rb
  • config/environment.rb
  • config/environments/development.rb
  • config/environments/production.rb
  • config/environments/test.rb
  • config/initializers/cors.rb
  • config/initializers/filterparameterlogging.rb
  • config/initializers/inflections.rb

Встановлення ruby 3.0.3 на Mac

  • нижче наведені кроки, які я встановив на своєму Big Sur
brew update  
brew upgrade rbenv  
rbenv install -l  
rbenv install 3.0.3  
gem install bundle  
rbenv global 3.0.3  
rbenv rehash
  • Примітка: Я тестував з ruby 3.1, і деякі з гемів, що використовуються, мали проблеми, тому я змінив на ruby 3.0.3

Виконання оновлення

  • Видаліть Gemfile.lock
  • Оновіть Gemfile наступним чином:

Чому потрібен гем ‘net-http’

  • тому що деякі попередження з'являються після оновлення
  • warning: protocol.rb:66: warning: already initialized constant Net::ProtocRetryError

Виконайте bundle update

  • це оновить rails до 7 і встановить необхідні геми
  • після завершення перевірте вашу версію rails всередині проекту
  • виконайте rails -v, переконайтеся, що показується версія 7.0.1 або вище

Виконайте rails app:update

  • вам буде запропоновано перезаписати деякі файли, і вибрати Y для перезапису
  • цей крок важливий і встановить необхідні налаштування
  • цей крок також додасть 3 міграційних файли для activestorage всередині config/db_
  • якщо ви не використовуєте active_storage, або використовуєте інші геми для керування завантаженням/вивантаженням файлів, наприклад, paperclip або shrine, ви можете видалити всі 3 міграційних файли, які щойно додалися
  • якщо ви використовуєте rails active_storage, ці 3 файли додадуть міграції для ваших записів active storage для роботи з rails 7
  • виконайте rails db:migrate, якщо ви використовуєте active storage

Відкрийте config/initializers/newframeworkdefault_7.0.rb

  • прочитайте інструкцію всередині цього файлу і увімкніть нові налаштування, щоб перевірити, чи ваша система може працювати з налаштуваннями rails 7
  • після того, як ви увімкнете опції всередині цього файлу
  • перезапустіть сервер rails
  • і перевірте в браузері, відкривши URL localhost:3000
  • якщо ваші додатки працюють без проблем, переходьте до наступного кроку

Налаштування load_defaults на 7

  • зупиніть сервер rails
  • відкрийте config/application.rb
  • змініть config.loaddefaults 6.0 на **config.loaddefaults 7.0**
  • це означає, що ви будете використовувати налаштування rails 7 у вашому додатку
  • запустіть сервер rails
  • перевірте в браузері

Відновлення налаштувань, які були перезаписані оновленням rails

  • Оскільки оновлення rails перезаписує наше конфігурацію, нам потрібно відновити її
  • Ось деякі з моїх власних файлів, які я порівняв з резервною копією і відновив конфігурацію
  • config/environments/development.rb
  • config/environments/production.rb
  • config/application.rb
  • нижче наведені налаштування, які відсутні після виконання команди оновлення rails
config.active_job.queue_adapter = :resque  
config.action_mailer.delivery_method = :postmark  
config.action_mailer.postmark_settings = ...


config.eager_load_paths << Rails.root.join('lib')
  • Я використовую resque для active job (Active Job), і postmark як SMTP сервіс
  • І мені потрібно підключити деякі файли з папки root/lib для виклику JWT (Json Web Token)
  • Знову перевірте і порівняйте ці файли з вашою резервною копією, щоб зекономити час на вирішення проблем.
  • Після того, як ви відновите вашу конфігурацію, перезапустіть сервер і перевірте додатки через браузер.

Режим автоматичного завантаження для Zeitwerk

  • Вам потрібно переконатися, що всі файли в вашому додатку сумісні з режимом Zeitwerk
  • Це стосується того, як ви називаєте модулі та класи відповідно до імен файлів
  • Наприклад, у вас є pdf файли в папці app/pdfs/marketing/invoicedetailpdf.rb

  • Наведений приклад показує різницю між режимом Zeitwerk і класичним режимом

На щастя, rails надає команду для перевірки

  • rails runner ‘p Rails.autoloaders.zeitwerk_enabled?’
  • ця команда перевіряє, чи увімкнено Zeitwerk
  • rails zeitwerk:check
  • ця команда перевіряє, чи сумісні всі файли вашого додатку з Zeitwerk
  • якщо все добре, з'явиться результат all is good
  • якщо ні, буде виведено ім’я файлу, і ви маєте виправити його перед тим, як продовжити

Встановлення importmap і hotwire

  • Як зазначив DHH, rails 7 замінює Webpacker, Turbolinks, UJS на import maps плюс Turbo і Stimulus від Hotwire як за умовчанням.
  • Ви можете дізнатися більше на https://hotwired.dev/.
  • Оскільки мій додаток використовує Sprockets, ось кроки, які я виконав

Встановлення importmap

  • оскільки gemи importmap і hotwire-rails вже встановлені з попереднього кроку, я просто встановив їх
  • виконайте rails importmap:install

Встановлення hotwire

  • виконайте rails hotwire:install

Заміна turbolinks на turbo

  • оскільки hotwire turbo заміняє turbolinks, ось кроки, які я виконав
  • відкрийте файл app/assets/javascripts/application.js (оскільки я використовую Sprocket)
  • видаліть рядок //= require turbolinks

Використовуючи ваш текстовий редактор, знайдіть в папці app/views/

  • знайдіть turbolinks:load, замініть на turbo:load
  • збережіть і закрийте всі файли

Використовуючи ваш текстовий редактор, знайдіть в папці app/assets/javascripts/

  • знайдіть div data-turbolinks, замініть на div data-turbo
  • збережіть і закрийте всі файли

Об’єднання Sprocket з importmap

  • Змініть ім’я файлу app/assets/javascripts/application.js на будь-яке, яке вам підходить. Я змінив на application_pipeline.js
  • Причина зміни: оскільки нова папка з javascript також використовує application.js всередині app/javascript/application.js
  • Створіть один маніфест-файл app/assets/config/manifest.js
  • (якщо папка config не існує, ви можете створити її вручну)
  • нижче наведено вміст для моїх налаштувань

  • ../images для доступу до папки всередині app/assets/images

  • ../stylesheets .css для доступу до .css файлів всередині app/assets/stylesheets

  • ../javascript .js для доступу до .js файлів всередині app/assets/javascript

  • ../../javascript .js для доступу до js файлів всередині app/javascript, до нової папки, створеної при встановленні importmap-rails

  • ../../../vendor/javascript для доступу до js файлів всередині кореневої папки rails/vendor

Налаштування для application.html.erb

  • відкрийте файл app/views/layouts/application.html.erb і змініть

Додати список попередньо скомпільованих файлів для production

  • відкрийте файл config/initializers/assets.rb
  • змініть і збільшити номер версії, якщо хочете попередньо скомпілювати все
  • Rails.application.config.assets.version = “3.3”
  • Ось приклад, ви можете збільшити номер, наприклад, до 3.4 або 4.0

  • як ви можете побачити, на другому рядку вище я додав application_pipeline.js до цього списку активів

  • виконайте попередню компіляцію, запустивши rails assets:precompile

Деякі дії, де потрібно вимкнути turbo

  • Деякі форми, наприклад, при вході та використанні devise, потрібно вимкнути turbo

Якщо ви використовуєте devise gem,

  • відкрийте файл views/devise/sessions/new.html.erb
  • і додайте data-turbo=”false” вище

Деякі форми, які потребують спливаючого вікна, також потребують data-turbo=”false”

Остання перевірка перед розгортанням у production

  • запустіть ваші тести, щоб переконатися, що вони проходять
  • якщо у вас немає завершених тестів, перевірте
  • увійдіть в систему
  • протестуйте частину вашого програмного забезпечення, яку найбільше використовують ваші користувачі
  • спробуйте завантажити файли, завантажити та роздрукувати pdf
  • якщо все працює, тоді можете продовжити публікацію на production

Встановлення в production

  • завантажте дані на production сервер, я використовую rsync
  • перейдіть у папку вашого додатку для rails production

Перекладено з: How I upgrade my apps to rails 7