如何为新模板添加路线?

Mik*_*awn 7 ruby ruby-on-rails 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>
Run Code Online (Sandbox Code Playgroud)

simulation控制器和操作的名称在哪里是方法的名称SimulationController.

我把它添加到我的 routes.rb

  resources :simulations, except: [:edit]

  resources :simulations do
    collection do
     get 'current_state'
     post 'current_state'
   end
 end
Run Code Online (Sandbox Code Playgroud)

在我SimulationController班上我添加了一个新方法,即

  def current_state
   byebug
  end
Run Code Online (Sandbox Code Playgroud)

我的问题?路线不会重新指向current_state方法.相反,它正在重定向到http://localhost:3000/simulations/{someID}

此重定向正在调用show操作.

def show
 ...
end
Run Code Online (Sandbox Code Playgroud)

我该怎样才能完成这项工作并让<%= @simulation.dat %>线路可以访问new.html.erb.位置new.html.erb在以下路径中

views/simulations/index.html.js
views/similations/show.html.js
views/simulations/new.html.erb
Run Code Online (Sandbox Code Playgroud)

这可能是一个基本问题,但我是rails 4的新手.先谢谢.

编辑-1

get_state方法的Defcontroller

 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
Run Code Online (Sandbox Code Playgroud)

Aet*_*rus 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
Run Code Online (Sandbox Code Playgroud)

请注意,原始collection块将更改为member块.块和块
之间的区别在于,您需要为块中的每个路径提供资源ID,而块中的那些路径不需要资源ID .collectionmembermembercollection

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

UPDATE

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

更新结束

rake routes在您的控制台中运行(或者bundle exec rake routes如果您安装了多个版本的rails),您将看到所有路径以及列出的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
...
Run Code Online (Sandbox Code Playgroud)

根据Prefix列,视图中的链接应该是

<%= link_to 'Show Current State', current_state_simulations_path(simulation), :class => 'btn btn-primary'%>
Run Code Online (Sandbox Code Playgroud)

或者简而言之

<%= link_to 'Show Current State', [:current_state, simulation], :class => 'btn btn-primary'%>
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

并修改你的SimulationsController:

def get_state
  @simulation = current_user.simulations.find(params[:id])
  not_found! unless @simulation
  # ...
  render 'new'
end
Run Code Online (Sandbox Code Playgroud)

最佳实践
对于动态页面Web应用程序,不要为非GET请求呈现视图!

为什么?因为如果用户将某些数据发布到您的Web应用程序,然后刷新他/她的浏览器,该请求将再次发送,并且您的数据库被污染了.对于PATCH,PUT和DELETE请求也是如此.

如果非GET请求成功,您可以用户重定向到GET路径,如果非GET请求失败,则可以用户重定向到400页.