我是Ruby和Rails的新手,对于为新模板渲染和添加路径有点困惑。
我已关注link_to
代码
<td colspan="3">
<%= link_to 'Show Current State', simulation, :action => :current_state, :class => 'btn btn-primary'%>
</td>
其中simulation
是控制器的名称,而action是SimulationController
中方法的名称。
我在routes.rb
resources :simulations, except: [:edit]
resources :simulations do
collection do
get 'current_state'
post 'current_state'
end
end
在我的SimulationController
课程中,我添加了一种新方法,即
def current_state
byebug
end
我的问题?路由不会重定向到current_state
方法。相反,它会重定向到http://localhost:3000/simulations/{someID}
此重定向正在调用show
操作。
def show
...
end
如何解决这个问题,并在<%= @simulation.dat %>
中访问new.html.erb
行。 new.html.erb
的位置位于以下路径
views/simulations/index.html.js
views/similations/show.html.js
views/simulations/new.html.erb
这可能是一个基本问题,但我是第4个新手。事先谢谢。
get_state
controller
方法的默认值
def get_state
@simulation = current_user.simulations.find(params[:id])
return not_found if @simulation.nil?
.....
/// How to send `@simulation` into `state.html.erb` formally as `new.html.erb`
end
答案 0 :(得分:6)
您的代码中有太多未命中。
首先,您不需要2 resources :simulations
,只需将它们合并为一个:
resources :simulations, except: :edit do
member do
get 'current_state', action: 'get_state'
post 'current_state', action: 'change_state'
end
end
请注意,原始collection
块已更改为member
块
collection
块和member
块之间的区别在于您需要为member
块中的每个路由提供资源ID ,而没有资源ID collection
块中的那些是必需的。
另请注意,我在每个路由中添加了action: 'xxx'
,因此您必须在SimulationsController
中添加这两个操作,一个用于GET请求,另一个用于POST请求。
在这两项操作中,最后添加render 'new'
。
在您的控制台中运行rake routes
(如果您安装了多个版本的rails,则运行bundle exec rake routes
),您将看到所有路径以及列出的url辅助方法,如下所示:
Prefix Verb URI Pattern Controller#Action
current_state_simulations GET /simulations/:id/current_state simulations#get_state
current_state_simulations POST /simulations/:id/current_state simulations#change_state
...
根据前缀列,视图中的链接应为
<%= link_to 'Show Current State', current_state_simulations_path(simulation), :class => 'btn btn-primary'%>
或简而言之
<%= link_to 'Show Current State', [:current_state, simulation], :class => 'btn btn-primary'%>
不要return
进行操作,因为return
不会停止渲染
而是使用raise ActionController::RoutingError.new('Not Found')
将用户重定向到404页面。
您可以在ApplicationController
中定义实例方法:
class ApplicationController < ActionController::Base
private
def not_found!
raise ActionController::RoutingError.new('Not Found')
end
end
并修改您的SimulationsController
:
def get_state
@simulation = current_user.simulations.find(params[:id])
not_found! unless @simulation
# ...
render 'new'
end
最佳实践
对于动态页面Web应用程序,不为非GET请求呈现视图!
为什么呢?因为如果用户将某些数据发布到您的Web应用程序,然后刷新他/她的浏览器,该请求将再次发送,并且您的数据库被污染了。与PATCH,PUT和DELETE请求相同。
如果非GET请求成功,您可以将用户重定向到GET路径,如果非GET请求失败,则可以将用户重定向到。