#<ActionView::Base:0x0000000010f748> 的未定义方法“user_search_admin_path”

Undefined method `user_search_admin_path' for #<ActionView::Base:0x0000000010f748>

单击我的管理页面时出现此错误: "undefined method `user_search_admin_path' for #ActionView::Base:0x0000000010f748" on line 47 url: '<%= user_search_admin_path(:format=>:json) % >'.

我有一条通往“user_search”的路线,所以不确定是什么导致了这个错误。任何解决此错误的想法?

这是管理路由:

resources :admin, :as  => :admin, :only => [:index, :create, :destroy] do
    collection {
      get "user_search";
      get "group_search";
      post "toggle_logging";
      post "toggle_privs";
      get "export_permissions";
      get "export_roles";
    };

下面是我的代码文件:

index.html.erb

<% content_for :crumbs do %>
  <li class="last"><%= link_to("Administrators", admin_index_path) %></li>
<% end %>

<% content_for :javascripts do %>
  <script type="text/javascript">

    function toggleGroup(group, that){
      var el = "." + group;
      $(el).parent().toggle(0,"swing",function(){
      });
    }

    function highlightGroup(group, role){
      var even = $('tr td.' + group).parent('.even').children("."+role).css("background-color");
      var odd = $('tr td.' + group).parent('.odd').children("."+role).css("background-color");
      // $('tr td.' + group).parent('.even').children("."+role).animate({backgroundColor:"red", opacity:0.5},800, function(){
      //   $('tr td.' + group).parent('.even').children("."+role).css({"background-color": even, opacity:1.0});    
      // });
      // $('tr td.' + group).parent('.odd').children("."+role).animate({backgroundColor:"red", opacity:0.5},800, function(){
      //   $('tr td.' + group).parent('.odd').children("."+role).css({"background-color": odd, opacity:1.0});
      // });

      $('tr td.' + group).parent('.odd').children('.indented_description').animate({backgroundColor:"red", opacity:0.5},800, function(){
        $('tr td.' + group).parent('.odd').children('.indented_description').css({"background-color": odd, opacity:1.0});    
      });

      $('tr td.' + group).parent('.even').children('.indented_description').animate({backgroundColor:"red", opacity:0.5},800, function(){
        $('tr td.' + group).parent('.even').children('.indented_description').css({"background-color": even, opacity:1.0});    
      });
    }

    $(document).ready(autocomplete_users);

    function autocomplete_users() {
      $(".add_usernames").autocomplete({
        minLength: 3,
        source: function(request, response) {
          var copy = this.element;
          $.ajax({
            beforeSend: function(){
              $(copy).parent().siblings(".spinner_td").css("display", "block");
            },
            complete: function() {
              $(copy).parent().siblings(".spinner_td").css("display", "none");
            },
            url: '<%= user_search_admin_path(:format=>:json) %>',
            data: {
              q: request.term,
            },
            dataType: "json",
            success: function(data) {
              response(data);
            },
          })
        },
        parse: function(data) {
          var parsed = [];

          for ( var i = 0; i < data.length; ++i ) {
            var row = data[i];
            parsed[parsed.length] = {
            data: row,
            value: row,
            result: row
            };
          }

          return parsed;
        }
      });
    }

    $(document).ready(autocomplete_groups);

    function autocomplete_groups() {
      $(".add_groups").autocomplete({
        minLength: 3,
        source: function(request, response) {
          var copy = this.element;
          
          $.ajax({
            beforeSend: function(){
              $(copy).parent().siblings(".spinner_td").css("display", "block");
            },
            complete: function() {
              $(copy).parent().siblings(".spinner_td").css("display", "none");
            },
            url: '<%= group_search_admin_path(:format=>:json) %>',
            data: {
              q: request.term,
            },
            dataType: "json",
            success: function(data) {
              response(data);
            },
          })
        },
        parse: function(data) {
          var parsed = [];
          
          for ( var i = 0; i < data.length; ++i ) {
            var row = data[i];
            
            parsed[parsed.length] = {
              data: row,
              value: row,
              result: row
            };
          }
          return parsed;
        }
      });
    }

    function add_new_group() {
      $.ajax({
        url:'auth_role/auth_group_add',
        success: function(result) {
          //$(result).insertBefore('#add_new_group_button')
          $('.group_table').append(result);
          autocomplete_groups();
        }
      });
    };

    function add_user_to_role() {
      $.ajax({
        url:'auth_role/auth_user_add',
        success: function(result) {
          //$(result).insertBefore('#add_new_user_button')
          $('.user_table').append(result);
          autocomplete_users();
        }
      });
    };

    function render_auth_role_partial () {
      $.ajax({
        url: 'auth_role/' + $("#roles_select").val()+ '/auth_role_partial',
        success: function(result) {
          $("#edit_role_div").replaceWith(result);
          $("#roles_select").value = "<%= @role.id %>"
        }
      });
    };

    function show_new_role_form() {
      $("#selector_div").hide();
      $.ajax({
        url: 'auth_role/new',
        success: function(result) {
          $("#edit_role_div").replaceWith(result);
        }
      });
    };

    // so users cannot lock themselves out of managing users
    $(document).ready(function() {
      $('#perms_checkbox_form').submit(function () {
        if ($("input[id^='perm_role_task:manage_user_group']:checked").length == 0) {
          alert("There must be at least one role with permission to manage users.");
          return false;
        }
      });
    });

    function check_duplicate_role() {
      var new_name = $("input[id='name']").val();
      $.ajax({
        url: 'auth_role/check_duplicate_role',
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        data: {new_name: new_name},
        success: function(data) {
          if (data == true) {
            validate_role_form();
          } else {
            alert("Role already exists or is empty. Please choose another name.");
          }
        }
      });
    }

    function validate_role_form() {
      // Check that the role name is alphanumeric
      var role_name = $('#edit_role_div input[name="name"]').val();
      
      if (/[^\w\s]+/.test(role_name)) {
        alert("Role name can only contain letters, numbers, _, or whitespace");
        $('#edit_role_div input[name="name"]').css("background-color", "#FFB2B2");
        return;
      }
      
      if ($.trim(role_name).length < 1) {
        alert("Role name cannot be blank");
        $('#edit_role_div input[name="name"]').css("background-color", "#FFB2B2");
        return;
      }
      
      var groups = ($("input[id='auth_groups_name']"));
      var users = ($("input[id='users_']"));
      var group_names = [];
      var user_names= [];
      var submit_flag = 1;
      
      $.each(groups, (function(index, elem) {
        group_names.push($(elem).val());
      }))
      
      $.each(users, (function(index, elem){
        user_names.push($(elem).val());
      }))
      
      if (group_names.length > 0 || user_names.length > 0) {
        $.ajax({
          url: 'auth_role/check_groups_and_users',
          dataType: "json",
          contentType: "application/json; charset=utf-8",
          data: {group_names: group_names, user_names: user_names},
          success:function(data) { 
            $("input[id='auth_groups_name']").css("background-color", "white");
            $("input[id='users_']").css("background-color", "white");
            
            if (data.invalid_groups.length > 0) { 
              submit_flag = 0;
              // mark invalid groups
              alert("At least one group is not a valid group.");
              $.each(data.invalid_groups, function(index, elem) {
                var ind = group_names.indexOf(elem);
                $("input[id='auth_groups_name']").eq(ind).css("background-color", "#FFB2B2");
                //$("input[id='auth_groups_name'][value='nen_project']").parent().parent().append('<td>Not a valid group.</td>');
              });
            }
            
            if (data.invalid_users.length >0 ) {
              submit_flag = 0;
              alert("At least one user is not a valid user.");
              $.each(data.invalid_users, function(index, elem) {
                var ind = user_names.indexOf(elem);
                $("input[id='users_']").eq(ind).css("background-color", "#FFB2B2");
              });
            }

            if (submit_flag == 1) {
              $("#update_role_form").submit();
            }
          }
        });
      } else {
        $("#update_role_form").submit();
      }
    }

    function export_perms() {
      window.location.href = "<%= export_permissions_admin_path(:format => 'tsv') %>";
    };

    function export_roles() {
      window.location.href = "<%= export_roles_admin_path(:format => 'tsv') %>";
    };
  </script>
<% end %>

<% content_for :title do %>
  Administrator Panel
<% end %>

<h1><%= yield :title %></h1>

<h2>Build Logging</h2>
<%= form_tag("/admin/toggle_logging", :method =>"post", :id => "toggle_logging") do %>
  The build detailed logging is currently <%= "#{@system_settings.detailed_logging ? 'Enabled': 'Disabled'}" %>
  <br/><br/>
  <%= submit_tag "#{@system_settings.detailed_logging ? 'Disable' : 'Enable'} Logging" ,:class=>"submit_auth_button"%>
<% end %>
<hr>

<% row_class = "even"
  groups = []

  def replaceSpaces(str)
    if str.to_s.strip.length == 0
     return str
    else
      copy = str

      copy = copy.gsub " ", "_"
      copy = copy.gsub "-", "_"
      copy = copy.gsub ":", "_"
      copy = copy.gsub "__", "_"
      copy = copy.downcase
      return copy
    end
  end

  def cleanDescription(str)
    if str.to_s.strip.length == 0
     return str
    else
      copy = str
      copy = copy.gsub "Edit CR Field: ", ""
      copy = copy.gsub "Task: ", ""
      copy = copy.gsub "Element: ", ""
      return copy
    end
  end

  def cleanDependsOn(str)
    if str.to_s.strip.length == 0
     return str
    else
      copy = replaceSpaces(str)
      copy = copy.gsub "|", " "
      return copy
    end
  end
%>

<h2>Permissions For Roles </h2>
<%= link_to_function raw("#{image_tag('export.png')} Export Permissions as TSV"), "export_perms()" %>

</br>
</br>

<%= form_tag("/auth_permission/update", :method =>"put", :id => "perms_checkbox_form") do %>
    
<table>
  <tr>
    <th class='permissionname'> Permission </th>
    <% @roles.each do |role| %>
      <th class='rolename'><%=role.name %></th>
    <% end %>
  </tr>
  <% @permissions.each do |perm| %>
    <%= fields_for "perm_role[]", perm do |perm_fields| %>
      <% if !groups.include? perm.group %>
      <% groups << perm.group %>
      <tr class='group_header'>
        <td onclick='toggleGroup("<%="#{replaceSpaces(perm.group)}"%>", this)'><a href='javascript:void(0);' id='toggler'><%=perm.group%><span id='info_helper'>&nbsp;(click to toggle)</span></a></td>
        <% @roles.each do |perm_role| %>
          <td class='permission_chkbox all_<%=replaceSpaces(perm.group) %> all_<%=replaceSpaces(perm_role.name) %>'> <%= check_box_tag("group_#{replaceSpaces(perm.group)}_#{replaceSpaces(perm_role.name)}", "unchecked", false ) %>
        <% end %>
      </tr>
    <% end %>

    <tr class='<%= row_class %>'>
      <td class='indented_description'><%="#{cleanDescription(perm.description)}" %>
      <% if perm.depends_desc %>
        <br/>
        <span class='depends_description <%="#{cleanDependsOn(perm.depends_on)}" %>'>
          <%="#{perm.depends_desc}" %>
        </span>
      <% end %>
      </td>
      <% @roles.each do |perm_role| %>
        <td class='permission_chkbox <%=replaceSpaces(perm.group) %> <%=replaceSpaces(perm_role.name)%>'> <%= check_box_tag("perm_role[#{perm.name},#{perm_role.name}]", "", perm.authroles.include?(perm_role) )  %></td>
      <% end %>

      <% 
        if row_class == 'even'
          row_class = 'odd'
        else
          row_class = 'even'
        end
      %>
    <% end %>  
    </tr>
  <%end%>
</table>

<br/>

<%= submit_tag "Update Permissions" ,:class=>"submit_auth_button"%>
<% end %>


<script>
  <% usednames = [] %>
  <% jsgroups = [] %>
  <% @permissions.each do |perm| %>
    <% @roles.each do |perm_role| %>
      var elementId = '#<%="group_#{replaceSpaces(perm.group)}_#{replaceSpaces(perm_role.name)}"%>';
      <% if !jsgroups.include? "#{perm_role.name} #{perm.group}" %>
        <% jsgroups << "#{perm_role.name} #{perm.group}" %>
        
        $(elementId).click(function(){

          // Check all the children
          if(this.checked){
            $(elementId).prop("checked", true);
            //console.log($('.<%="#{replaceSpaces(perm.group)}.#{replaceSpaces(perm_role.name)}"%> input'))
             $('.<%="#{replaceSpaces(perm.group)}.#{replaceSpaces(perm_role.name)}"%> input').each(function() { 
              $(this).prop("checked", true) 
            });
          }
          else{
            $(elementId).prop("checked", false);
            $('.<%="#{replaceSpaces(perm.group)}.#{replaceSpaces(perm_role.name)}"%> input').each(function() { 
              $(this).prop("checked", false) 
            });
          }
        });
      <% end %>

      // Need to clear out this variable otherwise it'll get confused
      elementId = ""

      // Check if everything under that group/role is already checked
      // If it is then check the Group Header
      // If it's not don't do anything
      var is_all_checked = true;
      $('.<%="#{replaceSpaces(perm.group)}.#{replaceSpaces(perm_role.name)}"%> input').each(function(){ 
        if(!this.checked || typeof(this.checked) == "undefined") is_all_checked = false
      });
      if(is_all_checked){
        $('#<%="group_#{replaceSpaces(perm.group)}_#{replaceSpaces(perm_role.name)}"%>').prop("checked", true);
      }

      // If any of the children permission roles get change, let's figure out if we need to check/uncheck
      // the parent 
      $('.<%="#{replaceSpaces(perm.group)}.#{replaceSpaces(perm_role.name)}"%> input').change(function(){ 
        // Check if everythin in that gorup is already filled out
        var is_all_checked = true;
        $('.<%="#{replaceSpaces(perm.group)}.#{replaceSpaces(perm_role.name)}"%> input').each(function(){ 
          if(!this.checked || typeof(this.checked) == "undefined") is_all_checked = false
        });
        if(is_all_checked){
          $('#<%="group_#{replaceSpaces(perm.group)}_#{replaceSpaces(perm_role.name)}"%>').prop("checked", true);
        }

        if(this.checked){
        }
        else{
          // uncheck the parent if any of its children are unchecked
          $('#<%="group_#{replaceSpaces(perm.group)}_#{replaceSpaces(perm_role.name)}"%>').prop("checked", false);
          //console.log("uncheck parent");      
        }
      });

      <% t = ".#{replaceSpaces(perm.group)}.#{replaceSpaces(perm_role.name)} input" %>
      <% if !usednames.include? t %>
        <% usednames << t %>
        $('.<%="#{replaceSpaces(perm.group)}.#{replaceSpaces(perm_role.name)}"%> input').change(function(){ 
          var rolename = '<%="#{replaceSpaces(perm_role.name)}"%>';
          var that = this;
          var old_color = $(that).parent().parent().children().first().children('.depends_description').css('background-color')
          $(that).parent().parent().children().first().children('.depends_description').animate({backgroundColor:'red', opacity:0.75}, 500);
          $(that).parent().parent().children().first().children('.depends_description').animate({backgroundColor:old_color, opacity:1}, 100);
         
          var classes = $(that).parent().parent().children().first().children('.depends_description').attr("class");

          if(classes && classes != "") {
            classes = classes.split(" ") 
            for(var k in classes){
              if(classes[k] != "depends_description"){
                // console.log("toggle", classes[k])
                highlightGroup(classes[k], rolename);
              }
            }
          }
        });
      <% end %>
    <% end %>
  <% end %>
</script>

<hr/>

<h2> Roles </h2>
<%= link_to_function raw("#{image_tag('export.png')} Export Roles as TSV"), "export_roles()" %>

</br>
</br>

<% if @role %>
  <div id="selector_div">
    <table>
      <tr>
        <td> Select Role: </td>
        <td>
          <%= select_tag "roles_select", options_for_select(@roles.collect {|role_option| [role_option.name, role_option.id]}, :selected => @role.id), :onchange => "render_auth_role_partial()", :class=>"role_selection" %>
        </td>
        <td>
          <%= button_to_function "Create New Role", "show_new_role_form()", :class=>"small_auth_button" %>
        </td>
        <td>
        </td>
      </tr>
    </table>
  </div>
<% end %>

<hr>

<%= render :partial => 'auth_role_form', :locals => {:role => @role, :roles => @roles}%>

admin_controller.rb

class AdminController < ApplicationController
  before_action :check_permission

  def index
    puts "stepped in index"
    @system_settings = AuthSettings.first
    @permissions = AuthPermission.sort(:group.asc, :name.asc)
    @roles = AuthRole.all(:order => :name)
    @role = @roles.first
    @users = User.administrators

    respond_to do |format|
      format.html # index.html.erb
      format.xml { render :xml => @users, :status => :ok }
      format.json { render :json => @users, :status => :ok }
    end
  end

  def create
    usernames = params[:admin][:usernames].split(',')

    @users = []
    usernames.each do |username|
      username.strip!
      next if username.empty?

      begin
        @users << User.find_or_create_admin(username)
      rescue
        logger.error("Couldn't save user with name: #{username}")
      end
    end

    respond_to do |format|
      format.html { redirect_to(:action=>:index) }
      format.xml { render :xml => @users, :status=>:created }
      format.json { render :json => @users, :status=>:created }
      format.js { render :layout=>false }
    end
  end
  
  def destroy
    @user = User.find_by_name(params[:id])

    if @user
      @user.admin = false
      if @user.save
        respond_to do |format|
          format.html
          format.xml { render :xml => @user }
          format.js { render :layout => false }
        end
      end
    else
      redirect404
    end
  end
  
  def user_search
    username = params.delete(:q)

    if username
      @users = User.search_for_usernames(username)
      respond_to do |format|
        format.json { render :json => @users }
      end
    else
      # TODO: this is erroneous because this particular request is always going to be a JSON request via the view
      # If the request was made from the outside, and it was an HTML request, it's not going to render anything...
      # regardless of whether or not the q parameter was supplied
      flash[:error] = "You need to supply a 'q' parameter in order to search"
      respond_to do |format|
        format.html { render :action=>:index }
      end
    end
  end

  def group_search
    groupname = params.delete(:q)

    if groupname
      @groupnames = User.search_for_groups(groupname)
      respond_to do |format|
        format.json { render :json => @groupnames }
      end
    else
      # TODO: this is erroneous because this particular request is always going to be a JSON request via the view
      # If the request was made from the outside, and it was an HTML request, it's not going to render anything...
      # regardless of whether or not the q parameter was supplied
      flash[:error] = "You need to supply a 'q' parameter in order to search"
      respond_to do |format|
        format.html { render :action=>:index }
      end
    end
  end

  def toggle_logging
    Rails.logger.info params
    setting = AuthSettings.first


    setting.detailed_logging = !setting.detailed_logging

    Rails.logger.info "Logging is #{setting.detailed_logging}"

    if setting.save
      flash[:notice] = "Detailed logging #{setting.detailed_logging ? 'enabled' : 'disabled'}."
    else
      flash[:error] = "Could not change logging"
    end

    redirect_to admin_index_path
  end
  
  def toggle_privs
    current_user.admin_enabled = !current_user.admin_enabled

    if current_user.save
      flash[:notice] = "Administrative privileges #{current_user.admin_enabled ? 'enabled' : 'disabled'}."
    else
      flash[:error] = "Could not change your privilege level."
    end

    redirect_to admin_index_path
  end

  def export_permissions
    respond_to do |format|
      format.tsv do
        tsv = []
        column_headers = [:description, :depends_desc, :authroles]

        # Filter records.

        records = AuthPermission.sort(:group.asc, :name.asc)

        # Render TSV lines.
        records.each do |record|
          element_line = []
          column_headers.each do |column|
            begin
              
              if column == :authroles
                value_arr = []
                value = ""
                record.authroles.each do |role|
                  value_arr << role.name
                end unless !record.authroles
                value << value_arr.join(",")

              else
                value = eval("record.#{column}")
              end

              element_line << value
            rescue
              element_line << nil
            end
          end

          tsv << element_line.join("\t")
        end

        # Add column headers to the top of the matrix.
        tsv.unshift([column_headers].flatten.join("\t"))

        render :text => tsv.join("\r\n")
      end
    end
  end

  def export_roles
    respond_to do |format|
      format.tsv do
        tsv = []
        column_headers = [:name, :description, :groups, :users]

        # Filter records.
        records = AuthRole.all(:order => :name)

        # Render TSV lines.
        records.each do |record|
          element_line = []
          column_headers.each do |column|
            begin

              if column == :groups
                value_arr = []
                value = ""
                record.groups.each do |group|
                  value_arr << group.name
                end unless !record.groups
                value << value_arr.join(",")
              elsif column == :users
                value = record.users.join(",")
              else
                value = eval("record.#{column}")
              end

              element_line << value
            rescue
              element_line << nil
            end
          end

          tsv << element_line.join("\t")
        end

        # Add column headers to the top of the matrix.
        tsv.unshift([column_headers].flatten.join("\t"))

        render :text => tsv.join("\r\n")
      end
    end
  end
  
  private
  
  def check_permission
    ensure_task_permission('task:manage_user_group')
  end
end

根据您的路由定义,如果 GET 请求所需的 URI 是 /admin/user_search,那么您应该使用 user_search_admin_index_path - 注意 _index 后缀。