为什么在select_tag:onchange事件上调用this.form.submit()时,为不同的控制器调用错误的路由

时间:2014-10-14 20:39:19

标签: ruby-on-rails-4 routes form-submit selectionchanged

我设置了一个名为' dir_list'的select_tag。使用表单提交更改来调用方法。此方法' file_dir'将根据dir_list中的选择生成文件列表,并生成部分文件以显示显示文件列表的第二个列表框。

当我点击选择框中的选项' dir_list'时,会调用表单提交但我收到路由错误。 rails后端代码正在为同一项目中的不同控制器生成路由。

它应该呼叫的路线是:' / file_alias_filedata / file_dir'相反,它呼吁路由:' file_alias_filedata / file_alias_tfiles / file_dir'

当我正在处理问题时,我确实有一个单独的控制器,视图和路线名为' file_alias_tfiles'我的file_alias_filedata具有类似的代码,可以解决并处理相同UI功能中的不同问题。这两个集是完全独立的,我在我的file_alias_filedata代码中彻底检查了对tfiles的任何调用,而且没有!

为什么会发生这种情况?如何清除它?

有没有办法可以对我的form_tag和this.form.submit调用进行硬编码,这样就不会发生错误解释?

以下是我将选择更改为路由错误的日志文件中的内容:

Started POST "/file_alias_filedata/evaluate_media" for 10.25.241.142 at 2014-10-14 19:44:23 +0000
Processing by FileAliasFiledataController#evaluate_media as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"LmBkjhXsw19VzCVV0S7yZvX5aJ8KAcX9R8eSyYiN3aY=", "location"=>"miniprod", "dir_list"=>"/watchfolder/miniprod/inprocess", "filepath"=>"/watchfolder/showtimevod/BeautyShop_125727.mpg", "filepath2"=>"/watchfolder/showtimevod/BeautyShop_125727.mpg"}
  ^[[1m^[[35mFileAliasFiledata Load (0.8ms)^[[0m  SELECT  `file_alias_filedata`.* FROM `file_alias_filedata`  WHERE `file_alias_filedata`.`full_path` = '/watchfolder/showtimevod/BeautyShop_125727.mpg' AND `file_alias_filedata`.`deleted_b` = 0  ORDER BY `file_alias_filedata`.`id` ASC LIMIT 1
  Rendered file_alias_filedata/_dir_list.html.erb (1.4ms)
  Rendered file_alias_filedata/_dir_list.html.erb (1.0ms)
  Rendered file_alias_filedata/_list_files.html.erb (11.3ms)
  Rendered file_alias_filedata/_dir_list.html.erb (1.1ms)
  Rendered file_alias_filedata/_dir_list.html.erb (2.0ms)
  Rendered file_alias_filedata/_dir_list.html.erb (1.1ms)
  Rendered file_alias_filedata/_dir_list.html.erb (0.6ms)
  Rendered file_alias_filedata/_dir_list.html.erb (0.3ms)
  Rendered file_alias_filedata/index.html.erb within layouts/application (100.3ms)
Completed 200 OK in 3562ms (Views: 1040.0ms | ActiveRecord: 4.5ms)


Started GET "/file_alias_filedata/file_alias_tfiles/file_dir?dir_list=%2Fwatchfolder%2Fminiprod%2Finprocess" for 10.25.241.142 at 2014-10-14 19:44:27 +0000

ActionController::RoutingError (No route matches [GET] "/file_alias_filedata/file_alias_tfiles/file_dir"):
  actionpack (4.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (4.1.4) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.1.4) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.1.4) lib/rails/rack/logger.rb:20:in `block in call'
  activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in `block in tagged'
  activesupport (4.1.4) lib/active_support/tagged_logging.rb:26:in `tagged'
  activesupport (4.1.4) lib/active_support/tagged_logging.rb:68:in `tagged'
  railties (4.1.4) lib/rails/rack/logger.rb:20:in `call'
  actionpack (4.1.4) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'

这是我正在调用的控制器方法:(我可以在url中调用它,它显示默认列表文件。)

  def file_dir
    unless params[:dir_list].nil?
      @dir_path_choice2 = params[:dir_list]
    else  
      @dir_path_choice2 = '/watchfolder/indemandvod'
    end  
    @files = Dir.glob("#{@dir_path_choice2}/**/*.{mpg,mov}").map
    if @files.nil?
      @files = Dir.glob("/watchfolder/indemandvod/**/*.{mpg,mov}").map
    end
    render :partial => 'list_files', :locals => {:@list => @files }
  end  

以下是file_dir代码的控制器名称:

class FileAliasFiledataController < ApplicationController

注意:如上所述,有一个控制器叫: class FileAliasTfilesController&lt; ApplicationController中

它还有一个file_dir方法,但它们是单独的代码,应该通过它们的路由路径单独到达。

以下是我正在使用的控制器的已定义路由:FileAliasFiledata

Path / Url                                          Path                                Controller#Action
================================================================================================================================            
file_alias_filedata_index_path          GET /file_alias_filedata/index(.:format)    file_alias_filedata#index
file_alias_filedata_show_path           GET /file_alias_filedata/show(.:format) file_alias_filedata#show
file_alias_filedata_new_path            GET /file_alias_filedata/new(.:format)  file_alias_filedata#new
file_alias_filedata_create_path         GET /file_alias_filedata/create(.:format)   file_alias_filedata#create
file_alias_filedata_edit_path           GET /file_alias_filedata/edit(.:format) file_alias_filedata#edit
file_alias_filedata_update_path         GET /file_alias_filedata/update(.:format)   file_alias_filedata#update
file_alias_filedata_destroy_path    GET /file_alias_filedata/destroy(.:format)  file_alias_filedata#destroy
file_alias_filedata_file_dir_path   GET /file_alias_filedata/file_dir(.:format) file_alias_filedata#file_dir

以下是索引文件中的form_tag设置,该文件围绕为部分渲染设置的所选dir_list div:

<%= form_tag(:url => '/file_alias_filedata/file_dir', :method => :get, :id => 'dir_select_tag2') do %>
<div id="dir_list">
    <%= render :partial => 'dir_list', :locals => {:dir_choice => @radio_button_value } %> 
     </div><br />

我也尝试使用form_tag格式并获得相同的结果:

<%= form_tag({:controller => 'file_alias_filedata', :action => 'file_dir', :method => :get}, {:id => 'dir_select_tag'}) do %>

以下是包含select_tag的_dir_list部分代码:onchange =&gt; this.form.submit()

   <div> 
    <label>Select Directory Path:</label><br />
        <% if dir_choice== "miniprod" %> 
            <% @dir_list = Dir["/watchfolder/miniprod/*"] %>               
        <% elsif dir_choice== "watch" %> 
                <% @dir_list = Dir["/watchfolder/*"].reject{ |f| f[%r{^/watchfolder/miniprod}] || f[%r{^/watchfolder/aspera_console}]} %>  
        <% elsif dir_choice== "archive" %> 
              <% @dir_list = Dir["/archive/*"] %> 
        <% elsif dir_choice== 'local'%> 
              <% @dir_list = Dir["/home/silver/test/*"] %>  
        <% else  %> 
          <% @dir_list = ["/watchfolder/aspera_console/"] %>  
        <% end %>
        <%= select_tag 'dir_list', options_for_select(@dir_list, @selected_dir_list), :onchange => "this.form.submit();", :with => "'dir_list='+this.options[this.selectedIndex].value" %> 
  </div>

如何让它拨打正确的路线?任何人都可以解释为什么会这样吗?

1 个答案:

答案 0 :(得分:1)

在此代码中:

<%= form_tag(:url => '/file_alias_filedata/file_dir', 
             :method => :get, 
             :id => 'dir_select_tag2') do %>

您将一个哈希作为参数传递给form_tag()。文档说form_tag()定义如下:

form_tag(url_for_options = {}, options = {}, &block)

请注意,form_tag()将两个哈希作为前两个参数。在你的代码中,你传递了form_tag()一个哈希,所以哈希被分配给第一个参数变量,即url_for_options。该变量被传递给名为url_for()的方法。对于url_for(),文档非常混乱,但最重要的是url_for()不理解Hash中的任何键。这些键应该在分配给第二个参数变量的哈希值中,即options

您可以通过两种不同的方式重写form_tag():

<%= form_tag( '/file_alias_filedata/file_dir', 
             :method => :get, 
             :id => 'dir_select_tag2') do %>

...传递一个String和一个Hash作为参数,并将String分配给参数变量url_for_options,并将Hash分配给参数变量options

或者:

<%= form_tag({controller: file_alias_filedata, action: file_dir},
             :method => :get, 
             :id => 'dir_select_tag2') do %>

...将两个哈希作为参数传递。

  

rails后端代码正在为不同的路由生成路由   控制器在同一个项目中。   任何人都可以解释为什么会这样吗?

ActionController :: Base#url_for docs说:

  

生成新网址时,可能会从中填写缺失值   当前请求的参数。例如,url_for:action =&gt;   &#39; some_action&#39;将保留当前的控制器

http://www.rubydoc.info/docs/rails/2.3.8/ActionController/Base:url_for

因为传递给url_for()的哈希没有:controller key:

<%= form_tag(:url => '/file_alias_filedata/file_dir', 
             :method => :get, 
             :id => 'dir_select_tag2') do %>

...无论params [:controller]是什么时候url_for()使用该erb代码来构造url。同样,你的Hash没有:action键,所以params [:action]也被用来构造url。然后,因为url_for()使用了选项method: 'get',所以form_tag()方法使用POST的默认方法。最后,如果您在浏览器中检查表单的html,您会注意到url_for()无法理解的任何选项,例如: :url:id:method,url_for()将它们添加到网址的末尾,以形成查询字符串.e.g。 ?id=dir_select_tag2&method=get&url=...

此外,您错过了结果<% end %>,因为&#39; do&#39;在你的form_tag()语句中。

此外,所有这些代码:

    <% if dir_choice== "miniprod" %> 
        <% @dir_list = Dir["/watchfolder/miniprod/*"] %>               
    <% elsif dir_choice== "watch" %> 
            <% @dir_list = Dir["/watchfolder/*"].reject{ |f| f[%r{^/watchfolder/miniprod}] || f[%r{^/watchfolder/aspera_console}]} %>  
    <% elsif dir_choice== "archive" %> 
          <% @dir_list = Dir["/archive/*"] %> 
    <% elsif dir_choice== 'local'%> 
          <% @dir_list = Dir["/home/silver/test/*"] %>  
    <% else  %> 
      <% @dir_list = ["/watchfolder/aspera_console/"] %>  
    <% end %>

...与生成html无关,所以它应该在控制器中。

在这一行中,

select_tag 'dir_list', options_for_select(@dir_list, @selected_dir_list)

@selected_dir_list未定义。

这个select_tag()选项:

:with => "'dir_list='+this.options[this.selectedIndex].value"

将在<select>上创建一个如下所示的html属性:

<select with="'dir_list='+this.options[this.selectedIndex].value"  ...>

这是一个毫无意义的属性。你能否发布一下你读到的关于带有选项的轨道方法? Google表示没有,但根据您的帖子,我知道必须至少有一个。

你的变量/控制器/动作名称通常很糟糕。你给你的表单一个&#34; select_tag&#34;的ID,这根本没有意义。怎么样&#34; form_for_dir_select&#34;或&#34; dir_form&#34;?如果您从不需要代码帮助,可以根据需要为变量命名。如果您需要帮助,并且您的变量名称不清楚,则没有人会费心阅读您的代码(因为我认为您已经找到了)。

最后,当你发布文件时,你需要发布他们的完整路径名 - 不只是说&#34;这是控制器&#34;。