【发布时间】:2021-04-27 23:33:01
【问题描述】:
我的 Rails 应用程序中有一个页面,它是一个控制器的显示操作,但它包含一个提交以创建另一个控制器的表单。这对于简单地将创建表单提交到第二个控制器来说很好,但是因为表单包含在备用控制器的显示操作中,所以我不能轻易地在表单上显示验证错误。这是结构的基本概念:
class VendorsController < ApplicationController
def show
@vendor = […]
end
end
<!-- vendors_controller/show -->
<h1><%= @vendor.name %></h1>
<%= form_with model: Order, local: true do |f| %>
<%= f.hidden_field :vendor_id, value: @vendor.id %>
[…]
<% end %>
class OrdersController < ApplicationController
def create
@order = […]
if @order.save
[…]
else
render 'new' # Not where user came from, actually want to go to vendors_controller/show
end
end
end
我发现在 vendors_controller/show 的“新”上下文中处理创建订单的唯一方法是将 OrdersController#create 移动到 VendorsController 内的自定义 create_order 方法,但这会将核心 REST 逻辑移动到一个模型到不同的控制器,感觉就像一个主要的代码气味。来自移动工程背景,我们可以将屏幕拆分为多个子视图,并使用独立的控制器来处理不同的元素,但这当然在 Web 上并不可行,因为单个控制器处理传入的请求和响应。
构建此行为的正确方法是什么,以便我可以保留OrdersController 的大部分 REST 功能,同时还将新操作“嵌入”到另一个控制器拥有的视图中?我想将Order 相关逻辑保留在OrdersController 中,但重定向回VendorsController#show 会破坏验证中的错误,将来我可能还想要一个具有相同逻辑但与VendorsController 分开的OrdersController#new 路由。
【问题讨论】:
-
从概念上讲,您实际上可以将视图拆分为不同的“控制器”,但在 Web 上使用 JavaScript 和 XHR 请求完成。
标签: ruby-on-rails ruby model-view-controller architecture controller