如何为新模板添加路由?

时间:2015-07-04 22:59:32

标签: ruby-on-rails ruby ruby-on-rails-4

我是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个新手。事先谢谢。

修改-1

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

1 个答案:

答案 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块已更改为membercollection块和member块之间的区别在于您需要为member块中的每个路由提供资源ID ,而没有资源ID collection块中的那些是必需的。

另请注意,我在每个路由中添加了action: 'xxx',因此您必须在SimulationsController中添加这两个操作,一个用于GET请求,另一个用于POST请求。

更新

在这两项操作中,最后添加render 'new'

END OF UPDATE

在您的控制台中运行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'%>

更新Edit-1

不要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请求失败,则可以将用户重定向到。