【问题标题】:undefined method `map' for nil:NilClass with DataTables用于 nil:NilClass 的未定义方法“map”与 DataTables
【发布时间】:2014-12-15 13:21:28
【问题描述】:

我刚刚实现了基于 Ryan Bates 的 rails cast #340 'http://railscasts.com/episodes/340-datatables?autoplay=true' 的数据表,我收到了这个错误 'undefined method `map' for nil:NilClass'。我所看到的所有地方,人们都在说这是因为你试图调用的内容是未定义的,但在这种情况下,我不确定为什么这是一个错误,因为它正在被定义,我已经按照这个 rails cast 到最后一个细节。

我得到的错误是“undefined method `map' for nil:NilClass” 堆栈跟踪如下:

Showing /Users/calligouser/Documents/CalligoProjects/cloudcentrev2/app/views/ips/index.html.erb where line #7 raised:

<li class="left"><%= select_tag 'ip_status_id', options_for_select(@ip_statuses, @status_id), { prompt: "All" } %></li>

在定义@ip_statuses 时,控制器中会出现此错误.map。代码进入模型,在该模型中检索值的哈希值,如下所示:

STATUSES = { 0 => "Unallocated",
           1 => "Allocated",
           2 => "Reserved",
           3 => "Transient"
}

我正在尝试在 IP 索引视图中加载 IP 地址数据表。

IP 控制器(索引)

def index

    @ips = Ip.all

    respond_to do |format|
      format.html
      format.json { render json: IpsDatatable.new(view_context) }
    end

    @ip_statuses = Ip::STATUSES.map {|key,value| [value,key]}
end

用于数据表选项的 ips_datatable.rb 文件

class IpsDatatable
  delegate :params, :h, :link_to, :number_to_currency, to: :@view

  def initialise(view)
    @view = view
  end

  def as_json(options = {})
    {
      sEcho: params[:sEcho].to_i
      iTotalRecords: Ip.count,
      iTotalDisplayRecords: ips.total_entries,
      aaData: data
    }
  end


private

  def data
    ips.map do |ip|
      [
        link_to(ip.ip_address, ip),
        h(ip.system_name),
        h(ip.description),
        h(ip.system_location),
        h(ip.status)
      ]
    end
  end

  def ips
    @ips ||= fetch_ips
  end

  def fetch_ips
    ips = Ip.order("#{sort_column} #{sort_direction}")
    ips = ips.page(page).per_page(per_page)
    if params[:sSearch].present?
      ips = ips.where("name like :search or category like :search", search: "%#{params[:sSearch]}")
    end
    ips
  end

  def page
    params[:iDisplayStart].to_i/per_page + 1
  end

  def per_page
    params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : 10
  end

  def sort_column
    columns = %w[ip_address system_name system_location description status]
    columns[params[:iSortCol_0].to_i]
  end

  def sort_direction
    params[:sSortDir0] == "desc" ? "desc" : "asc"
  end

end

IPs JQuery 文件

 jQuery ->

  # -------------------------------------------------------------------------
  # DataTables Server Side
  # -------------------------------------------------------------------------
  $('#ip-table').dataTable
    sPaginationType: "full_numbers"
    bJQueryUI: true
    bProcessing: true
    bServerSide: true
    sAjaxSource: $('#ip-table').data('source')

IP 表表单视图

<table id="ip-table" class="full display" data-source="<%= products_url(format: "json") %>">
        <thead>
          <tr>
            <th>Ip address</th>
            <th>System name</th>
            <th>Description</th>
            <th>System location</th>
            <th>Status</th>
            <th>Edit / Delete</th>
          </tr>
        </thead>

        <tbody>

        </tbody>

      </table>

编辑:我发现应用程序没有超出 respond_to 块,所以我尝试在 ip_datatables 文件中进行调试,并且在到达文件中的代码之前应用程序似乎失败了.我在 format.json 代码行之后使用了 puts '....',它确实达到了这一点,但由于某种原因,它没有从 ip_datatables 文件中返回。

【问题讨论】:

    标签: jquery ruby-on-rails datatable server-side


    【解决方案1】:

    你不写stacktrace,所以我不知道错误在哪里。

    无论如何...修复ips_datatable.rb中的错字

    方法名称是def initialize 而不是initialise

    【讨论】:

    • 是的,对不起。我习惯了英文拼写。我已更新问题以包含该错误位置
    【解决方案2】:

    数据函数引用 ips,此时 ips 似乎为空。我的猜测是它是您的 fetch_ips 函数中的行

    ips = ips.page(page).per_page(per_page)
    

    虽然我不能说你想要它是什么,但我可以说你需要重命名你的 page 和 per_page 函数,以便更清楚该行在做什么。

    您应该从我提到的那一行开始注释掉多余的步骤以使其正常工作。实际上,您应该首先将 fetch_ips 函数简化为

    ips = Ip.order("#{sort_column} #{sort_direction}")
    

    并测试看看这是否至少有效。然后,一旦你让它工作,你就可以开始添加东西了。

    您可能还想让codereview 的人在您按预期工作后查看它。

    编辑:如果这不起作用,您可以尝试将行 ips.map do |ip| 调整为类似于 ips.tap{|a| puts a}.map do |ip| 的行,以便查看此时 ips 的实际情况。确认此时它为空,表明这确实是错误指向的地方,然后通过代码找出原因......如果此时它实际上不是空,那么有错误指向的其他地方,不包含在您发布的代码中。这里的目标是确定异常在哪里被抛出,然后向后工作以确定它被抛出的原因。

    我的猜测是/是它与 fetch_ips 函数有关,您可以尝试通过将数据函数 ips.map 更改为 Ip.all.map 来消除该函数。但这又是假设 ips.map 是引发该异常的行,因此请确认。

    【讨论】:

    • 我按照您的建议注释了 fetch_ips 方法中的其余代码,但是错误仍然存​​在。关于 page 和 per_page 方法,我相信它们被称为 page 和 per_page 因为它们控制表格的分页,所以没有理由根据表格本身给它们一个特定的名称。
    • @JackO'Connor 我编辑了我的答案以提供更多想法来帮助您调试它。另外,我并不是说您应该将 page 和 per_page 重命名为特定于表的名称,我只是认为您应该将它们命名为 page 和 per_page 以外的名称。在同一范围内拥有两个同名的函数是自找麻烦。
    【解决方案3】:

    好的,我实际上发现了这个问题。在控制器中,我删除了除了响应块之外的所有内容并将此代码放在它上面:

    @ip_statuses = Ip::STATUSES.map {|key,value| [value,key]}
    
    if !session[:ip_status_id].nil? then @status_id = session[:ip_status_id] else @status_id = 1 end
    @ips = @ips.where(status: @status_id) unless @status_id == ""
    

    然后,我从 ips_datatable 文件的委托中删除了 :h,并删除了正在使用的“h”方法的所有实例。然后我在 ips_datatable 文件中填写了缺少的逗号。

    我还必须从 html 表中删除编辑/删除标题,因为数据表无法识别它,因为它实际上不是数据库中的列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多