如果表单本身从不持久化,您能否使表单对象用于新建和编辑操作?

Can you make a form object work for new and edit actions if the form itself is never persisted?

我正在尝试使表单对象适用于 new Useredit User 操作。表单对象通过它的 save 方法创建或更新 User,但表单对象本身永远不会持久化,因此 Rails 总是尝试创建 POST,即使我在 simple_form_for url.

中指定不同的路由

有没有办法让它同时适用于这两个动作?

UsersController.rb:

class Admin::UsersController < AdminController
  def new
    @user_form = UserForm.new(account_id: current_account.id)
  end

  def create
    @user_form = UserForm.new(user_form_params)
    if @user = @user_form.save
      flash[:success] = "User created"
      redirect_to admin_user_path(@user)
    else
      render "new"
    end
  end

  def edit
    @user_form = UserForm.new(existing_user: @user, account_id: current_account.id)
  end

  def update
    if @user.update(user_form_params)
      flash[:success] = "User saved"
      redirect_to admin_user_path(@user)
    else
      render "edit"
    end
  end
end

UserForm.rb

class UserForm
  include ActiveModel::Model
  include ActiveModel::Validations::Callbacks

  attr_accessor :fname, :lname, :email

  def initialize(params = {})
    super(params)
    @account = Account.find(account_id)
    @user = existing_user || user
  end

  def user
    @user ||= User.new do |user|
      user.fname = fname
      user.lname = lname
      user.email = email
    end
  end
    
  def save
    @user.save
    @user
  end
end

_form.html.erb

<%= simple_form_for @user_form, url: (@user.present? ? admin_user_path(@user) : admin_users_path) do |f| %>

    <%= f.input :fname  %>
    <%= f.input :lname %>
    <%= f.input :email %>
    <%= f.submit %>
    
end

new/create 流程工作正常,但编辑现有 User returns

No route matches [POST] "/admin/users/69"
class UserForm
  # ...

  def to_model
    @user
  end
end
<%= simple_form_for @user_form, url: [:admin, @user_form] do |f| %>
    <%= f.input :fname  %>
    <%= f.input :lname %>
    <%= f.input :email %>
    <%= f.submit %>
end

当您将记录传递给 form_for(SimpleForm 包装)时,form_withlink_to 多态路由助手会调用 to_model.model_name.route_keysingular_route_key,具体取决于如果模型是 persisted?。传递 [:admin, @user_form] 将导致多态路由助手使用 admin_users_path 而不仅仅是 users_path.

在普通型号上 to_model 只是 returns 自己。

https://api.rubyonrails.org/v6.1.4/classes/ActionDispatch/Routing/PolymorphicRoutes.html