Ruby on rails Rails控制器中嵌套资源的条件路由#编辑操作,取决于请求来自何处
我有一个Foo资源Ruby on rails Rails控制器中嵌套资源的条件路由#编辑操作,取决于请求来自何处,ruby-on-rails,redirect,controller,routing,Ruby On Rails,Redirect,Controller,Routing,我有一个Foo资源有许多条。我将嵌套资源用于有限数量的操作,但在其他情况下,我更喜欢将路由保持为浅条。导航到条形图对象的编辑视图有两种方法-从包含foo的嵌套路径,或从不嵌套在foo中的较浅的Bar路径。例如,用户可以在/foos/[:foo_id]/bar/[:bar_id]的页面上单击编辑按钮;或者从/bar/[:bar\u id]开始 在第一种情况下,我希望控制器在更新记录后将用户重定向回父foo页面:/foos/[:foo\u id]。在第二种情况下,我希望它重定向到条:/bar的索引视
有许多条。我将嵌套资源用于有限数量的操作,但在其他情况下,我更喜欢将路由保持为浅条。导航到条形图对象的编辑视图有两种方法-从包含foo
的嵌套路径,或从不嵌套在foo
中的较浅的Bar
路径。例如,用户可以在/foos/[:foo_id]/bar/[:bar_id]
的页面上单击编辑按钮;或者从/bar/[:bar\u id]
开始
在第一种情况下,我希望控制器在更新记录后将用户重定向回父foo页面:/foos/[:foo\u id]
。在第二种情况下,我希望它重定向到条
:/bar
的索引视图。我相信我需要在栏
控制器中的编辑
操作中使用某种条件,它将告诉Rails在执行#更新
后要去哪里
# config/routes.rb
resources :foos do
resources :bars, only: [:new, :edit]
end
resources :bars
# bin/rake routes:
foo_bars POST /foos/:foo_id/bars(.:format) bars#create
new_foo_bar GET /foos/:foo_id/bars/new(.:format) bars#new
edit_foo_bar GET /foos/:foo_id/bars/:id/edit(.:format) bars#edit
bars GET /bars(.:format) bars#index
POST /bars(.:format) bars#create
new_bar GET /bars/new(.:format) bars#new
edit_bar GET /bars/:id/edit(.:format) bars#edit
bar GET /bars/:id(.:format) bars#show
PATCH /bars/:id(.:format) bars#update
PUT /bars/:id(.:format) bars#update
DELETE /bars/:id(.:format) bars#destroy
条的控制器
:
# app/controllers/bar_controller.rb
def edit
@bar = bar.find(params[:id])
@foo = @bar.foo
end
def update
@bar = bar.find(params[:id])
@foo = @bar.foo
respond_to do |format|
if @bar.update_attributes(bar_params)
format.html { redirect_to @foo, notice: "bar successfully updated" }
else
format.html { render action: "edit" }
end
end
end
我正在尝试更改#update
操作中的重定向到@foo
行,以便根据#edit
操作的启动位置,有条件逻辑将@foo
切换到@bar
。我尝试了以下方法来测试调用#edit
操作时是否存在params[:foo]
,为重定向设置一个实例变量
def edit
if params[:foo]
@redirect_page = @foo
else
@redirect_page = @bars
end
@bar = bar.find(params[:id])
@foo = @bar.foo
end
def update
# code omitted...
format.html { redirect_to @redirect_page, notice: "bar successfully updated" }
# code omitted...
end
这不管用。Rails状态无法重定向到nil代码>。我还尝试了一些基于#edit
操作中的URI(request.referer).path
的测试,但没有成功
我仍然不完全清楚Rails的魔力是如何在控制器中发生的。我相信#edit
操作是定义重定向条件的合适位置(或通过#edit
操作中调用的方法),因为控制器将在那里“看到”传入请求并知道它来自何处。但我不太明白如何捕获这些信息,并将其传递给#update
。感谢您的指导。在您的编辑表单中,添加一个隐藏的\u字段\u标签
:
<%= hidden_field_tag "route", request.env['PATH_INFO'] %>
然后在您的控制器中,您可以有一个if
语句,并根据参数[:route]
是什么,使用一个重定向到
。。使用request.env['PATH\u INFO]
的params[:route]方法对我不起作用,因为表单中的'PATH\u INFO'变量提供了传递给bar#update
操作的路径,而不是启动bar#edit
操作的路径
在/foos/[:id]
的父foo页面中单击“编辑”后,参数散列为:
>> params
=> {"controller"=>"bars", "action"=>"edit", "foo_id"=>"3786", "id"=>"16"}
首次访问表单时,params[:route]
没有值-只有在编辑表单中单击“更新”后,隐藏字段才会添加到params散列中:
>> params[:route]
=> "/foos/3786/bars/16/edit"
这可能可行,但需要构建逻辑来解析路由,以便重定向到/foos/[:foo_id]
事实证明,使用Railsflash
方法存储重定向回源页面的路径更简单。为此,我在BarsController中调用了一个自定义方法set\u redirect\u path
,然后在bars\edit
中调用它。这将为闪存中的源设置一个值,该值可在栏#update
中找到。也许有更好/更传统的方法来实现这一点,但这似乎是一个干净和简单的方式来做我想要的
# app/controllers/bars_controller.rb
def edit
set_redirect_path
@bar = bar.find(params[:id])
@foo = @bar.foo
end
def update
@bar = bar.find(params[:id])
@foo = @bar.foo
respond_to do |format|
if @bar.update_attributes(bar_params)
format.html { redirect_to flash[:source], notice: "bar successfully updated" }
format.xml { head :ok }
else
format.html { render action: "edit" }
format.xml { render xml: @bar.errors, status: :unprocessable_entity }
end
end
end
private
def set_redirect_path
flash[:source] = URI(request.referer).path
end
这种方法的一个优点是,我现在可以摆脱共享部分app/views/bar/\u list.html.haml
中的条件逻辑,该逻辑用于确定单击“编辑”按钮是否应路由到Edit\u foo\u bar\u path
或Edit\u bar\u path
(即,如果@foo
存在,则选择前者)。因此,我可以删除嵌套资源:bar
的:edit
。由于闪存捕获请求的传入源并将其存储在#update
操作中以供参考,因此所有编辑请求都可以使用相同的编辑条路径
,而不管它们来自何处。更新后,Rails将用户重定向到他们启动编辑操作的点。您正在定义编辑操作的重定向页面。您需要在更新操作时执行此操作。在编辑表单上,您可以将defoo\u id
设置为隐藏字段。但我需要捕获调用\edit
时请求的来源。如果我将逻辑放在#update
操作中,我就看不到原始请求。例如,在编辑表单的web控制台中,URI(request.referer).path
返回/foos/[:foo\u id]
。提交后(在#update
操作中调用控制台),它返回/bar/[:bar\u id]/edit
。这并没有告诉我在哪里调用了#edit
。顺便说一句,我意识到,#edit
是为foo中的嵌套资源公开的;但是,使用共享视图显示条形图#索引
和foo#show
页面上的条形图。试图避免附加的视图逻辑