Ruby on Rails 7 Многошаговая форма с логикой нескольких моделей

В настоящее время я борюсь с созданием многоэтапной формы, где каждый шаг создает экземпляр модели.

В данном случае у меня есть 3 модели:

  1. Пользовательский план
  2. Связь
  3. GameDashboard

Так как ассоциация такая:

У user есть user_planconnection принадлежит user_plangame_dashboard принадлежит connection

Я хотел бы создать мастер, чтобы позволить current_user создать game_dashboard, пройдя через многошаговую форму, где он также создает соединение и экземпляр user_plan.

Для этого я посмотрел на Wicked gem и начал создавать логику из game_dashboard (которая последняя). Как только мне пришлось столкнуться с генерацией формы, я почувствовал, что начинать снизу — не лучшее решение.

Вот почему я здесь, чтобы попросить о помощи:

Как лучше реализовать этот мастер? Начиная снизу (game_dashboard) или начиная сверху (use_plan)?

Поскольку я не прошу помощи в коде на данный момент, я не писал никакой логики контроллера или модели, если это будет кому-то полезно, я выложу!

Большое спасибо


РЕДАКТИРОВАТЬ

Поскольку мне нужно разрешить только один процесс за раз, но разрешить несколько процессов, чтобы избежать значений параметров, я решил создать новую модель, называемую «онбординг», где я обрабатываю состояния шагов, проверяя каждый раз, когда шаг

🤔 А знаете ли вы, что...
Этот фреймворк позволяет легко масштабировать приложения с ростом нагрузки и объема данных.


259
1

Ответ:

Решено

Самый простой способ — положиться на стандартный шаблон MVC Rails.

Просто используйте методы контроллера create и update для ссылки на форму следующей модели (вместо представления show или index).

Например.

class UserPlansController < ApplicationController
  ...

  def create
    if @user_plan = UserPlan.create(user_plan_params)
      # the next step in the form wizard process:
      redirect_to new_connection_path(user_id: current_user, user_plan_id: @user_plan.reload.id)
    else
      @user_plan = UserPlan.new(user: current_user)
      render :new
    end    
  end

  ...

  # something similar for #update action
end

Для маршрутов у вас есть два варианта:

Вы можете вложить все:

# routes.rb

resources :user do
  resources :user_plan do
    resources :connection do
      resources : game_dashboard
    end
  end
end

Плюсы:

Это упростит настройку ваших ассоциаций в ваших контроллерах, потому что все ваши маршруты будут иметь то, что вам нужно. Например.:

/users/:user_id/user_plans/:user_plan_id/connections/:connection_id/game_dashboards/:game_dashboard_id

Против:

Ваши маршруты и помощники по ссылкам будут очень длинными и интенсивными в направлении «дна». Например.

game_dashboard_connection_user_plan_user_path(:user_id, :user_plan_id, :connection_id, :game_dashboard)

Вы можете просто вручную связать «шаги» вашего мастера вместе

Плюсы:

URL-адреса и помощники не такие сумасшедшие. Например.

new_connection_path(user_plan_id: @user_plan.id)

С помощью одной значимой переменной URL: user_plan_id=1 вы можете искать все выше по течению. например.:

@user_plan = UserPlan.find(params['user_plan_id'])
@user = @user_plan.user

Против:

(не так много "против", потому что вы, вероятно, все равно это сделаете)

Если вам нужно отобразить информацию о «родительских» записях, вы должны сначала выполнить поиск модели в своих контроллерах:

class GameDashboardController < ApplicationController
  # e.g. URL: /game_dashboards/new?connection_id=1
  def new
    @connection = Connection.find(params['connection_id'])
    @user_plan = @connection.user_plan
    @user = @user_plan.user
    @game_dashboard = GameDashboard.new(connection: @connection)
  end
end