NoMethodError (undefined method `name' for nil:NilClass)
受付中
回答 1
投稿
- 評価
- クリップ 0
- VIEW 1,572
以下の様なDeviseのジェネレータを用いて作成したモデルがあり、「:html => { :multipart => true }」オプションを追加したフォームからfile_field(icon)に画像ファイルを指定してcreateメソッドにsubmitしたところ、タイトルの「NoMethodError (undefined method `name' for nil:NilClass)」が発生しました。ただし、file_field(icon)に何も指定しないとicon以外は正しく保存されます。
db/schema.rb
ActiveRecord::Schema.define(version: 20141112025346) do
create_table "users", force: true do |t|
t.string "name", default: "", null: false
t.binary "icon", limit: 2147483647
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"
t.datetime "updated_at"
end
end
以下にMVCを示します。(関係のある部分のみ)
app/models/user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
end
app/views/users/registrations/new.html.erb
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, :html => { :multipart => true }, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :name, "お名前" %><br />
<%= f.text_field :name, autofocus: true %></div>
<div><%= f.label :icon, "アイコン" %><br />
<%= f.file_field :icon %></div>
<div><%= f.label :email, "メールアドレス" %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password, "パスワード" %><br />
<%= f.password_field :password, autocomplete: "off" %></div>
<div><%= f.label :password_confirmation, "パスワード(確認用)" %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
<%= render "users/shared/links" %>
app/controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
before_filter :configure_permitted_parameters
def new
super
end
def create
super
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:icon, :name, :email, :password, :password_confirmation) }
end
def sign_up_params
devise_parameter_sanitizer.sanitize(:sign_up)
end
end
動作①
name・icon・email・password・password_confirmationを入力し、Sign upをクリックすると「undefined method `name' for nil:NilClass」と怒られます。

動作②
iconにはなにも指定しないでSign upをクリックするとicon以外はきちんと登録されます。
User.all
User Load (0.4ms) SELECT `users`.* FROM `users`
=> [#<User id: 3, name: "山田太郎", icon: nil, email: "yamada@example.com", encrypted_password: "$2a$10$gjpCKyJ/lrAnp.ZsC.HCb.mPWyRprQBfbZ5dYHEaSgq...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2014-11-15 15:37:37", last_sign_in_at: "2014-11-15 15:37:37", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at: "2014-11-15 15:37:37", updated_at: "2014-11-15 15:37:37">]
createメソッドには以下のパラメータが送信されています。
{"utf8"=>"✓",
"authenticity_token"=>"pWAkwJoYBj05BzgSyB0K1ItGcVXE+VkoCtXLoTVPrjw=",
"user"=>{"name"=>"山田太郎",
"icon"=>#<ActionDispatch::Http::UploadedFile:0x007fbb02c09d00 @tempfile=#<Tempfile:/var/folders/9s/9qds0lbn6n52gbz8b7ykxpgr0000gn/T/RackMultipart20141115-2132-1mqosjq>,
@original_filename="icon.jpg",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name=\"user[icon]\"; filename=\"icon.jpg\"\r\nContent-Type: image/jpeg\r\n">,
"email"=>"yamada@example.com",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"},
"commit"=>"Sign up"}
エラーが起きている場所を特定する為にDevise::RegistrationsControllerのcreateメソッド
# POST /resource
def create
build_resource(sign_up_params)
resource_saved = resource.save
yield resource if block_given?
if resource_saved
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_flashing_format?
sign_up(resource_name, resource)
respond_with resource, location: after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_flashing_format?
expire_data_after_sign_in!
respond_with resource, location: after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
@validatable = devise_mapping.validatable?
if @validatable
@minimum_password_length = resource_class.password_length.min
end
respond_with resource
end
end
をコピーして当てはめてみると
resource_saved = resource.save
でエラーが発生していました。
ここの手前の
build_resource(sign_up_params)
でresourceが作られていないのか?と思ったので次の様に中身を見てみるときちんとUserモデルが作成されていました。
logger.debug "=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
logger.debug "=-=-=-=-= する前 =-=-=-=-="
logger.debug "=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
logger.debug resource.inspect
build_resource(sign_up_params)
logger.debug "=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
logger.debug "=-=-=-=-= した前 =-=-=-=-="
logger.debug "=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
logger.debug resource.inspect
logger.debug "=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
logger.debug "=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-= する前 =-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
nil
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-= した前 =-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#<User id: nil, name: "山田太郎", icon: #<ActionDispatch::Http::UploadedFile:0x007fd9ee63fe00 @tempfile=#<Tempfile:/var/folders/9s/9qds0lbn6n52gbz8b7ykxpgr0000gn/T/RackMultipart20141116-5573-dj5hix>, @original_filename="icon.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"user[icon]\"; filename=\"icon.jpg\"\r\nContent-Type: image/jpeg\r\n">, email: "yamada@example.com", encrypted_password: "$2a$10$OEukJ2lZMoFv4/G7CnkZyu7m.Mi8ekH56q2b1B4UUjS...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil>
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
なにかアドバイスを頂けたらと思います。よろしくお願いします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 90.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2014/11/21 08:47