如果表单本身从未持久化,您能否使表单对象适用于新操作和编辑操作?
Posted
技术标签:
【中文标题】如果表单本身从未持久化,您能否使表单对象适用于新操作和编辑操作?【英文标题】:Can you make a form object work for new and edit actions if the form itself is never persisted? 【发布时间】:2021-10-25 16:50:18 【问题描述】:我正在尝试使表单对象适用于 new
User
和 edit
User
操作。表单对象通过它的save
方法创建或更新User
,但表单对象本身永远不会持久化,因此即使我在simple_form_for
url 中指定了不同的路由,Rails 也总是尝试进行 POST。
有没有办法让它对这两种操作都起作用?
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
新建/创建流程运行良好,但编辑现有 User
会返回
No route matches [POST] "/admin/users/69"
【问题讨论】:
如果您查看我给您的上一个问题的答案,它实际上解决了这个问题。 @max 对不起,我又问了一遍,但我以为我解释错了。你能解释一下to_model
方法的作用吗?它确实解决了路由问题
在普通型号上to_model
只是返回自我。当您将记录传递给form_for
或link_to
时,多态路由助手调用to_model.model_name.route_key
或singular_route_key
,具体取决于模型是否为persisted?
。传递[:admin, @user_form]
将导致多态路由助手使用admin_users_path
而不仅仅是users_path
。 api.rubyonrails.org/v6.1.4/classes/ActionDispatch/Routing/…
【参考方案1】:
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_with
或link_to
时,多态路由助手调用to_model.model_name.route_key
或singular_route_key
,具体取决于模型是否为persisted?
。传递[:admin, @user_form]
将导致多态路由助手使用admin_users_path
而不仅仅是users_path
。
在普通模型上to_model
只是返回自我。
https://api.rubyonrails.org/v6.1.4/classes/ActionDispatch/Routing/PolymorphicRoutes.html
【讨论】:
以上是关于如果表单本身从未持久化,您能否使表单对象适用于新操作和编辑操作?的主要内容,如果未能解决你的问题,请参考以下文章