-1

I setting a up a select_tag called 'dir_list' to use form submit on change to call a method. This method 'file_dir', will generate a list of files based on the selection from dir_list and the render a partial to display a second list box showing the file list.

When I click on a selection in the select box 'dir_list', the form submit is called but I get a routing error. The rails backend code is generating a route for a different controller in the same project.

The route that it should be calling is: '/file_alias_filedata/file_dir' instead it is calling for route: 'file_alias_filedata/file_alias_tfiles/file_dir'

As I am working through issues, I do have a separate controller,view and route named 'file_alias_tfiles' that has similar code ad my file_alias_filedata to troubleshoot and work on different issues within the same UI functionality. These two sets are completely separate and I checked thoroughly in my file_alias_filedata code for any calls to tfiles and there are none!

Why is this happening and how do I clear it?

Is there a way I can hard code my form_tag and this.form.submit call so no mis-interpretation can happen?

Here is what is in the log file from the point that I change the selection to the routing error:

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'

Here is the controller method I am calling: (I can call this in the url and it display the default list file.)

  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  

Here is the controller name for the file_dir code above:

class FileAliasFiledataController < ApplicationController

Note: As mentioned there is a controller called: class FileAliasTfilesController < ApplicationController

That also has a file_dir method but they are separate code and should be reached separately by their routing paths.

Here are my defined routes for the controller I am using: 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

Here is the form_tag setup in the Index file that surrounds the selected dir_list div set up for partial rendering:

<%= 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 />

I also tried this format with form_tag and get the same result:

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

Here is the _dir_list partial code that contains the select_tag that is :onchange => 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>

How do I get this to call the correct route? Can anybody explain why this is happening?

  • Hi Carol, you seem to have received a really thorough answer below, but you appear not to have accepted it, voted on it, or replied to it, despite having logged in since it was posted. Was it not of assistance in this case? – halfer Feb 07 '16 at 08:40

1 Answers1

1

In this code:

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

You are passing one Hash as an argument to form_tag(). The docs say form_tag() is defined like this:

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

Notice that form_tag() takes two hashes as the first two arguments. In your code, you passed form_tag() one Hash, so the Hash was assigned to the first parameter variable, i.e. url_for_options. That variable is passed to a method called url_for(). The docs are pretty confusing for url_for(), but the bottom line is that url_for() does not understand any of the keys in your Hash. Those keys should have be in a Hash assigned to the second parameter variable, i.e. options.

You can rewrite your form_tag() two different ways:

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

...which passes one String and one Hash as arguments, and the String gets assigned to the parameter variable url_for_options, and the Hash gets assigned to the parameter variable options.

Or:

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

...which passes two Hashes as arguments.

The rails backend code is generating a route for a different controller in the same project. Can anybody explain why this is happening?

The ActionController::Base#url_for docs say this:

When generating a new URL, missing values may be filled in from the current request's parameters. For example, url_for :action => 'some_action' will retain the current controller

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

Because the Hash you passed to url_for() does not have a :controller key:

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

...whatever params[:controller] was when that erb code executed was used by url_for() to construct the url. Similarly, your Hash does not have an :action key, so params[:action] also was used to construct the url. Then, because url_for() ate the option method: 'get', the form_tag() method used the default method of POST. Finally, if you check the html for the form in your browser, you will notice that for any options that url_for() didn't understand, e.g. :url, :id, and :method, url_for() tacked them onto the end of the url to form a query string, .e.g. ?id=dir_select_tag2&method=get&url=....

Also, you are missing a closing <% end %> for the 'do' in your form_tag() statement.

In addition, all this code:

    <% 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 %>

...has nothing to do with generating html, so it should be in a controller.

And in this line,

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

@selected_dir_list is undefined.

And this select_tag() option:

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

will create an html attribute on the <select> that looks like this:

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

which is a meaningless attribute. Can you please post what rails method you read about that takes a :with option? Google says there are none, but based on your posts I know there must be at least one.

And your variable/controller/action names are generally horrible. You gave your form an id of "select_tag", which makes no sense at all. How about "form_for_dir_select" or "dir_form"? If you never need help with code, you can name your variables anything you want. If you need help, and your variable names aren't clear, no one is going to bother reading your code(as I think you are finding out).

Finally, when you post files you need to post their full path names--not just say "this is the controller".

7stud
  • 46,922
  • 14
  • 101
  • 127