NoMethodError-未定义的方法'map'为nil:NilClass

时间:2018-08-16 14:43:37

标签: ruby-on-rails ruby model-view-controller maps ruby-on-rails-5

我对Rails刚起步,并使用maps API构建商店定位器应用程序。我有一个关联的商店模型和厕所模型,以便用户在添加商店时可以选择商店是否有厕所。但是,尝试添加商店并为Toilet_available选择“否”时,我始终收到以下错误:

NoMethodError in Stores#create
Showing /mnt/c/Users/Me/Dropbox/coding/SpaetiApp/app/views/stores/_form.html.erb where line #7 raised:

undefined method `map' for nil:NilClass
Extracted source (around line #7):
5
6
7
8
9
10

    <%= f.input :address_line3, label: "Country", input_html: { value: "Germany"} %>
    <%= f.input :beer_cost, label: "Cost of a Berliner Pilsner" %>
    <%= select_tag(:toilet_id, options_for_select(@toilets), :prompt => "Toilet available?" ) %>
    <%= f.input :facilities, label: "Facilities" %>

    <%= f.button :submit %>

Trace of template inclusion: app/views/stores/new.html.erb

但是,当我为Toilet_available选择“是”时,我没有收到此错误。这是相关的文件。

存储控制器:

class StoresController < ApplicationController

    before_action :find_store, only: [:show, :edit, :update, :destroy]

    def index
        if params[:toilet].blank?
            @stores = Store.all.order("created_at DESC")
        else
            @toilet_id = Toilet.find_by(toilet_available: params[:toilet]).id
          @stores = Store.where(:toilet_id => @toilet_id).order("created_at DESC")
        end
    end

    def show
    end

    def edit
        @toilets = Toilet.all.map{ |t| [t.toilet_available, t.id] }
    end

    def update
        @store.toilet_id = params[:toilet_id] 
        if @store.update(store_params)
            redirect_to store_path(@store)
        else
            render 'edit'
        end
    end

    def new
        @store = current_user.stores.build
        @toilets = Toilet.all.map{ |t| [t.toilet_available, t.id] }
    end

    def create
        @store = current_user.stores.build(store_params)
        @store.toilet_id = params[:toilet_id] 

        if @store.save 
            redirect_to root_path
        else
            render 'new'
        end
    end

    def destroy
        @store.destroy
        redirect_to root_path
    end

    private

        def store_params
            params.require(:store).permit(:name, :address, :address_line2, :address_line3, :beer_cost, :toilet_id)
        end

        def find_store
            @store = Store.find(params[:id])
        end
end

Schema.rb:

ActiveRecord::Schema.define(version: 20180814220216) do

  create_table "stores", force: :cascade do |t|
    t.string "name"
    t.string "address"
    t.float "beer_cost"
    t.text "facilities"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.float "latitude"
    t.float "longitude"
    t.boolean "toilet"
    t.string "address_line2"
    t.integer "user_id"
    t.integer "toilet_id"
    t.string "address_line3"
  end

  create_table "toilets", force: :cascade do |t|
    t.string "toilet_available"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer "sign_in_count", default: 0, null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string "current_sign_in_ip"
    t.string "last_sign_in_ip"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

end

表格:

<%= simple_form_for @store,:html => { :multipart => true } do |f| %>
    <%= f.input :name, label: "Spaeti Name" %>
    <%= f.input :address, label: "Address" %>
    <%= f.input :address_line2, label: "City", input_html: { value: "Berlin" } %>
    <%= f.input :address_line3, label: "Country", input_html: { value: "Germany"} %>
    <%= f.input :beer_cost, label: "Cost of a Berliner Pilsner" %>
    <%= select_tag(:toilet_id, options_for_select(@toilets), :prompt => "Toilet available?" ) %>
    <%= f.input :facilities, label: "Facilities" %>

    <%= f.button :submit %>
<% end %>

1 个答案:

答案 0 :(得分:1)

当它点击create动作时,看起来'@ store.save'返回的是false,因此它呈现了'new'模板。但是,在create操作中未设置@toilets变量,因此模板将其视为nil。

也将此行添加到您的创建动作中,这将消除您看到的错误:

@toilets = Toilet.all.pluck(:toilet_available, :id) 

您还可以在before_action中将其设置为所需的操作:

before_action :set_toilets, except: [:show, :index]

private

def set_toilets 
  @toilets = Toilet.all.pluck(:toilet_available, :id) 
end