我对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 %>
答案 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