erb 数组迭代中 nil:NilClass 的未定义方法“each”
undefined method `each' for nil:NilClass on an erb array iteration
我目前在 Rails 5 应用程序中工作,您可以在其中搜索名字或姓氏,并且会显示该帐户的客户记录。但是我从搜索算法中得到了一个 Nil 对象 return。
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
如您所见,如果没有找到记录,假设 return 是一个空数组,但 return 是一个 Nil 对象。
customers/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]
首先你应该了解的是实例变量 return 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
。
我认为如果您只是将 @customer =
替换为 @customers =
就可以解决您的问题。
您可以使用#to_a 将 nil 转换为空数组
将其强制为 return 数组
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
我目前在 Rails 5 应用程序中工作,您可以在其中搜索名字或姓氏,并且会显示该帐户的客户记录。但是我从搜索算法中得到了一个 Nil 对象 return。
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
如您所见,如果没有找到记录,假设 return 是一个空数组,但 return 是一个 Nil 对象。
customers/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]
首先你应该了解的是实例变量 return nil
如果它们还没有被设置。如果你说 @fake_var == nil
如果你在此之前从未定义过 @fake_var
,那么它就是真的。您可以将其与常规局部变量进行对比,如果您在定义它们之前尝试使用它们,它们将引发 NoMethodError。例如,puts(fake_var)
将为 fake_var.
现在看看你的模板。不管怎样它都会循环遍历@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
。
我认为如果您只是将 @customer =
替换为 @customers =
就可以解决您的问题。
您可以使用#to_a 将 nil 转换为空数组
将其强制为 return 数组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