質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.60%

  • Ruby

    7337questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails 4

    2406questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

  • Devise

    242questions

    Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

NoMethodError (undefined method `name' for nil:NilClass)

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,428

HirokiShirai

score 4

こんにちは。

以下の様な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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

Rails 3.1からマルチパートオプションは付けなくてもRails側で自動判別されるはずですが、Railsのバージョンは3.1以上ですか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2014/11/21 08:47

    回答ありがとうございます。Railsのバージョンは4.1.4です。multipartオプション必要なかったのですね、ありがとうございます。しかしmultipartオプションを外してみましたが結果は変わりませんでした。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby

    7337questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

  • Ruby on Rails 4

    2406questions

    Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

  • Devise

    242questions

    Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。