Как обрабатывать данные форм?ruby-67

Обработка данных форм - фундаментальная задача веб-разработки. Рассмотрим полный цикл работы с формами в Ruby-экосистеме.

Основные подходы к обработке форм

1. Нативные HTML-формы

Самый базовый способ, работающий во всех фреймворках:

<form action="/submit" method="post">
  <input type="text" name="user[name]">
  <input type="email" name="user[email]">
  <button type="submit">Отправить</button>
</form>

Обработка в Sinatra:

post '/submit' do
  name = params[:user][:name]
  email = params[:user][:email]
  # Обработка данных...
end

2. Form Helpers в Rails

Rails предоставляет мощные хелперы для работы с формами:

<%= form_with model: @user do |form| %>
  <%= form.text_field :name %>
  <%= form.email_field :email %>
  <%= form.submit %>
<% end %>

Контроллер Rails:

def create
  @user = User.new(user_params)

  if @user.save
    redirect_to @user
  else
    render :new
  end
end

private

def user_params
  params.require(:user).permit(:name, :email)
end

Валидация данных

1. Модельная валидация

class User < ApplicationRecord
  validates :name, presence: true
  validates :email,
    presence: true,
    format: { with: URI::MailTo::EMAIL_REGEXP },
    uniqueness: true
end

2. Параметры strong parameters

Защита от массового назначения атрибутов:

def user_params
  params.require(:user).permit(:name, :email, :age)
end

Обработка загрузки файлов

1. Использование Active Storage

<%= form.file_field :avatar %>

Контроллер:

def user_params
  params.require(:user).permit(:name, :email, :avatar)
end

2. Прямая загрузка

// Пример с Activestorage
input.addEventListener('change', (event) => {
  const files = event.target.files;
  Array.from(files).forEach(file => uploadFile(file))
});

Безопасность форм

  1. CSRF-защита:

    • Rails автоматически добавляет токен в формы
    • Проверяется при обработке POST-запросов
  2. Экранирование HTML:

    • Автоматически в helpers типа text_field
    • Вручную: ERB::Util.html_escape(str)
  3. Параметры запроса:

    • Всегда использовать strong parameters
    • Никогда не использовать params.to_unsafe_h без необходимости

AJAX-формы

1. Remote формы в Rails

<%= form_with model: @user, local: false do |form| %>
  <!-- поля формы -->
<% end %>

Обработка ответа:

$(document).on('ajax:success', 'form', function(event) {
  const [data, status, xhr] = event.detail;
  // Обработка успешного ответа
});

2. Fetch API

fetch('/users', {
  method: 'POST',
  body: new FormData(formElement)
})
.then(response => response.json())
.then(data => console.log(data));

Кастомные решения

Для сложных форм можно использовать:

  1. Form Objects:

    class RegistrationForm
      include ActiveModel::Model
    
      attr_accessor :name, :email, :password
    
      validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
      # ... другие валидации
    end
    
  2. Dry-validation:

    schema = Dry::Schema.Params do
      required(:name).filled(:string)
      required(:email).filled(:string, format?: URI::MailTo::EMAIL_REGEXP)
    end
    

Тестирование форм

Системные тесты

test "create user" do
  visit new_user_path

  fill_in 'Name', with: 'Test User'
  fill_in 'Email', with: 'test@example.com'

  click_button 'Create User'

  assert_text 'User was successfully created'
end

Контроллер-тесты

test "should create user" do
  assert_difference('User.count') do
    post users_url, params: { user: { name: 'Test', email: 'test@example.com' } }
  end
end

Резюмируем

Обработка форм включает:

  1. Создание формы (HTML helpers или вручную)
  2. Прием и валидацию параметров
  3. Защиту от уязвимостей (CSRF, инъекции)
  4. Обработку разных типов данных (файлы, JSON)
  5. Гибкую работу с ошибками
  6. Поддержку различных сценариев (AJAX, SPA)

Ключевые практики:

  • Всегда использовать strong parameters
  • Валидировать данные на нескольких уровнях
  • Предпочитать Form Objects для сложных форм
  • Тестировать все сценарии работы с формами