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

时间:2018-10-17 00:29:23

标签: ruby-on-rails ruby rails-geocoder

我已经针对该特定错误检查了API,提供的答案无法解决我的问题。

我只是在尝试在线获取的“查找最近的位置”代码,而我的问题是,当我将这个代码实现到项目中时,我正在获取“未定义的方法“ each”,用于nil:NilClass错误” 。

我知道此错误是由于调用@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部分引起的,但我不太确定。

1 个答案:

答案 0 :(得分:0)

您没有指定发生此错误的控制器动作,但是根据您的代码,我想这是来自evaluatePostfix()方法的。问题可能是您试图不渲染布局,但是在设置show变量之前要这样做。因此,Rails将在创建实例变量之前进行渲染。要解决此问题,应在创建实例变量后将@locations行移至方法的末尾,例如:

render :layout => nil

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

app / controllers / books_controller.rb

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

在您的情况下,您有一个名为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的文件。因此,Rails仍然无法找到您的page文件。我假设您确实有一个page.html.erb文件,否则将收到其他错误,但是,如果您尝试从show.html.erb文件内部呈现HTML,则不会在{{ 1}}方法,除非您专门渲染该文件。

其他一些说明...

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