nil的未定义方法`map':带有DataTables的NilClass

时间:2014-12-15 13:21:28

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

我刚刚实现了基于Ryan Bates'rails'#340'http://railscasts.com/episodes/340-datatables?autoplay=true'的数据表,我收到了这个错误'未定义的方法`map'为nil:NilClass'。我看到的每个地方的人都在说这是因为你试图调用的是未定义的,但在这种情况下我不确定为什么这是一个错误,因为这是定义的,我已经跟着这个轨道转换到最后的细节。

我得到的错误是“未定义的方法`map'为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文件中返回。

3 个答案:

答案 0 :(得分:0)

你没有写堆栈跟踪,所以我不知道错误在哪里。

无论如何......修复你的ips_datatable.rb

中的typpo

方法名称为def initialize而不是initialise

答案 1 :(得分:0)

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

ips = ips.page(page).per_page(per_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实际上是什么在此刻。此时确认它为null,表明这确实是错误所指向的位置,然后通过代码来找出原因...如果它在该点实际上不为null,那么错误指向的其他位置,您发布的代码中不包含该错误。这里的目标是确定抛出异常的位置,然后向后工作以确定抛出异常的原因。

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

答案 2 :(得分:0)

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

@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表中删除编辑/删除标题,因为数据表不会识别它,因为它实际上不是数据库中的列。