Ruby on Rails - nil:NilClass 错误的未定义方法“each”

Ruby on Rails - undefined method `each' for nil:NilClass error

我已经检查了 API 我的具体错误,但提供的答案无法解决我的问题。

我只是在试验在线获得的 "find nearest location" 代码,我的问题是当我将此代码实施到一个项目时,我获得了 "undefined method `each' for nil:NilClass error"。

我知道这个错误是由于调用@something 时未定义。所以,这是我正在使用的代码和文件:

locations.rb

class Nearby_Location < ActiveRecord::Base
  geocoded_by :full_address
  after_validation :geocode, :if => :address_changed?

  def full_address
   [address, city, postcode].compact.join(',')
  end
end

locations_controller.rb

class Locations < ApplicationController
  def index
    @locations = Locations.all
    if params[:search].present?
      @locations = Locations.near(params[:search], 10, :order => :distance)
    else
      @locations = Locations.all.order("created_at DESC")
    end
  end

  def new
    @locations = Locations.new
  end

  def create
    @locations = Locations.new(location_params)
    if @locations.save
      flash[:success] = 'Place added!'
      redirect_to root_path
    else
      render 'new'
    end
  end

  def location_params
    params.require(:location).permit(:company_name, :address, :city,
                                    :postcode, :latitude, :longitude)
  end

  def show
    render :layout => nil
    @locations = Locations.find(params[:id])
  end

end

page.html.erb

<div class="container">
  <div class="starter-template">
    <h3>Find places near your location</h3>
    <p class="lead">Enter your address or zip code</p>
    <p><%= form_tag locations_path, :method => :get do %>
      <%= text_field_tag :search, params[:search], placeholder: "e.g Statue of Liberty, New York" %>
      <%= submit_tag "Search Near", :name => nil %>
      <% end %>
    </p>
  </div>

  <% @locations.each do |locations| %>
 <%= link_to locations do %>
  <%= locations.name %>
 <% end %>
<% end %>

</div>
</div>

scheme.rb

  create_table "locations", force: :cascade do |t|
    t.string "address"
    t.float "latitude"
    t.float "longitude"
  end

我修改了包含其他 API 答案的代码,但没有成功。我觉得这可能是由于代码的 def show 部分,但我不太确定。

你没有指定你在哪个控制器操作中遇到了这个错误,但是根据你的代码我猜它来自 show 方法。问题可能是您试图不渲染布局,但是您是在设置 @locations 变量之前这样做的。因此,Rails 在创建实例变量之前进入渲染。要修复,您应该在创建实例变量后将 render :layout => nil 行移动到方法的末尾,例如:

def show
  @locations = Locations.find(params[:id])
  render :layout => nil
end

但是,我认为根据您的文件名称,您可能没有完全理解此处发生的事件流程。默认情况下,在控制器操作结束时,Rails 将尝试通过从与控制器名称匹配的视图文件夹中查找与控制器操作匹配的文件名来呈现文件。例如:

app/controllers/books_controller.rb :

class BooksController < ApplicationController
  def index
    # Will automatically render `app/views/books/index.html.erb`
  end

  def show
    render :other_show_page # Will look for a file `app/views/books/other_show_page.html.erb` rather than `app/views/books/show.html.erb` because it was explicitly specified
  end
end

在你的例子中,你有一个名为 page.html.erb 的文件,但你没有控制器操作 (def page; end),你的任何其他操作也没有专门呈现一个名为 [=17= 的文件].因此,Rails 无论如何都无法找到您的 page.html.erb 文件。我假设你确实有一个 show.html.erb 文件,否则你会得到一个不同的错误,但是如果你试图从你的 page.html.erb 文件中渲染 HTML,它不会发生在您的 show 方法中,除非您专门渲染该文件。

一些其他注意事项...

  • 模型的名称通常应该是单数,而不是复数。您似乎使用 Locations 作为您的型号名称,而不是 Location.
  • 您的 show 方法 @locations 中的实例变量,尽管您使用的是 find ActiveRecord 查询。此查询 returns 单个对象,而不是多个对象的集合代理。因此,您的 @locations 变量命名有点误导, @location.
  • 可能更好
  • 如果您 尝试在您点击 show 方法时呈现 page.html.erb 文件,除非您这样做有某些特定原因是不必要的和不好的做法。您应该只将代码包含在 show.html.erb 文件中,然后让 Rails 自动呈现它,而不是创建您专门呈现的自定义文件。 Rails 约定优于配置,因此请尝试学习约定并遵循它们,直到您有充分的理由打破这种约定。