未定义的方法`each'for nil:NilClass在erb数组迭代中
问题描述:
我目前正在Rails 5应用程序中工作,您可以在其中搜索名字或姓氏,并显示该帐户的客户记录。不过,我正在从搜索算法返回一个Nil对象。未定义的方法`each'for nil:NilClass在erb数组迭代中
customers_controller:
class CustomersController < ApplicationController
def index
if params[:keywords].present?
@keywords = params[:keywords]
customer_search_term = CustomerSearchTerm.new(@keywords)
@customer = Customer.where(
customer_search_term.where_clause,
customer_search_term.where_args).
order(customer_search_term.order)
else
@customers = []
end
end
end
正如你可以看到,如果没有发现记录是假设返回一个空数组,但返回一个无对象。
客户/ index.html.erb
[![<header>
<h1 class="h2">Customer Search</h1>
</header>
<section class="search-form">
<%= form_for :customers, method: :get do |f| %>
<div class="input-group input-group-lg">
<%= label_tag :keywords, nil, class: "sr-only" %>
<%= text_field_tag :keywords, nil,
placeholder: "First Name, Last Name or Email Address",
class: "form-control input-lg" %>
<span class="input-group-btn">
<%= submit_tag "Find Customers", class: "btn btn-primary btn-lg" %>
</span>
</div>
<% end %>
</section>
<section class="search-results">
<header>
<h1 class="h3">Results</h1>
</header>
<table class="table table-striped">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Joined</th>
</tr>
</thead>
<tbody>
<% @customers.each do |customer| %>
<tr>
<td><%= customer.first_name %></td>
<td><%= customer.last_name %></td>
<td><%= customer.email %></td>
<td><%= l customer.created_at.to_date %></td>
</tr>
<% end %>
</tbody>
</table>
</section>][1]][1]
答
你应该了解的第一件事情是,如果他们没有被设置实例变量返回nil
。如果你说@fake_var == nil
这将是真实的,如果你在此之前从未定义@fake_var
。您可以将其与常规局部变量进行对比,如果您尝试在定义之前使用它们,则会引发NoMethodError。例如,puts(fake_var)
将引发fake_var的NoMethodError。
现在看看你的模板。不管它会循环通过@customers
。如果尚未设置@customers
,则会看到一个NoMethodError,因为您无法通过nil
拨打each
。
最后,看看你的控制器动作:
def index
if params[:keywords].present?
@keywords = params[:keywords]
customer_search_term = CustomerSearchTerm.new(@keywords)
@customer = Customer.where(
customer_search_term.where_clause,
customer_search_term.where_args).
order(customer_search_term.order)
else
@customers = []
end
end
具体的时params[:keywords].present?
情况。在这种情况下,您从未设置@customers
,因此当模板试图访问它时,它将为nil
。
我想如果你只是用替换它会解决你的问题。
答
您可以强制其使用#to_a它转换零到空数组阵列返回
def index
return [] unless params[:keywords]
@keywords = params[:keywords]
customer_search_term = CustomerSearchTerm.new(@keywords)
@customer = Customer.where(
customer_search_term.where_clause,
customer_search_term.where_args).
order(customer_search_term.order
).to_a
end