紙一重の積み重ね

35歳のエンジニアがなれる最高の自分を目指して、学んだことをこつこつ情報発信するブログです。

【13章】Railsチュートリアル中にNameError: uninitialized constant Micropost::PictureUploaderが出た時の対処法

発生した章

13.4.1 基本的な画像アップロードにて、CarrierWaveをインストールして、リスト 13.59: Micropostモデルに画像を追加するの通り修正したら、テストでエラーが出るようになった。

やったこと

CarrierWaveに画像と関連付けたモデルを伝えるために、mount_uploaderメソッドを使用する。引数に、属性名(今回はpicture)と、クラス名(PictureUploader)を指定する。

class Micropost < ApplicationRecord
  belongs_to :user
  default_scope -> { order(created_at: :desc) }
  mount_uploader :picture, PictureUploader
  validates :user_id, presence: true
  validates :content, presence: true, length: { maximum: 140 }
end

発生したエラー内容

Micropostモデルを呼び出した際に、以下のエラーが発生する。 NameError: uninitialized constant Micropost::PictureUploader

チュートリアルでは、この時点でのtestはgreenになると書かれているが、redになる。 (Micropostモデルから、mount_uploaderメソッドを削除するとgreenになる)

yokoyan:~/workspace/sample_app (user-microposts) $ rails test
Running via Spring preloader in process 9762
Started with run options --seed 39087

ERROR["test_profile_display", UsersProfileTest, 0.09379067993722856]
 test_profile_display#UsersProfileTest (0.09s)
NameError:         NameError: uninitialized constant Micropost::PictureUploader
            app/models/micropost.rb:4:in `<class:Micropost>'
            app/models/micropost.rb:1:in `<top (required)>'

 FAIL["test_content_should_be_at_most_140_characters", MicropostTest, 2.966606823960319]
 test_content_should_be_at_most_140_characters#MicropostTest (2.97s)
        Expected true to be nil or false
        test/models/micropost_test.rb:32:in `block in <class:MicropostTest>'

 FAIL["test_user_id_should_be_present", MicropostTest, 2.974773451918736]
 test_user_id_should_be_present#MicropostTest (2.97s)
        Expected true to be nil or false
        test/models/micropost_test.rb:22:in `block in <class:MicropostTest>'

 FAIL["test_content_should_be_present", MicropostTest, 2.9872157878708094]
 test_content_should_be_present#MicropostTest (2.99s)
        Expected true to be nil or false
        test/models/micropost_test.rb:27:in `block in <class:MicropostTest>'

 FAIL["test_micropost_interface", MicropostsInterfaceTest, 3.539895322872326]
 test_micropost_interface#MicropostsInterfaceTest (3.54s)
        "Micropost.count" didn't change by 0.
        Expected: 38
          Actual: 39
        test/integration/microposts_interface_test.rb:16:in `block in <class:MicropostsInterfaceTest>'

  59/59: [==================================================================================================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.68161s
59 tests, 245 assertions, 4 failures, 1 errors, 0 skips

参考情報

NameError: uninitialized constant Article::ImageUploader when using Carrierwave on rails 4.1.5

上記の記事を見ると、config/environment.rbの行末に、require 'carrierwave/orm/activerecord'を追記して解決したという人がいる。 他にも、springを再起動したら治ったという人もいる。

対策

springを再起動する。

yokoyan:~/workspace/sample_app (user-microposts) $ spring stop
Spring stopped.
yokoyan:~/workspace/sample_app (user-microposts) $ 
yokoyan:~/workspace/sample_app (user-microposts) $ spring start
Version: 1.7.2

Usage: spring COMMAND [ARGS]

Commands for spring itself:

  binstub         Generate spring based binstubs. Use --all to generate a binstub for all known commands. Use --remove to revert.
  help            Print available commands.
  server          Explicitly start a Spring server in the foreground
  status          Show current status.
  stop            Stop all spring processes for this project.

Commands for your application:

  rails           Run a rails command. The following sub commands will use spring: console, runner, generate, destroy, test.
  rake            Runs the rake command

再度テストを実行。 無事にエラーが解決しました。

yokoyan:~/workspace/sample_app (user-microposts) $ rails test
Running via Spring preloader in process 13599
Started with run options --seed 41861

DEPRECATION WARNING: ActionDispatch::IntegrationTest HTTP request methods will accept only================                   ] 84% Time: 00:00:02,  ETA: 00:00:00
the following keyword arguments in future Rails versions:
params, headers, env, xhr, as

Examples:

get '/profile',
  params: { id: 1 },
  headers: { 'X-Extra-Header' => '123' },
  env: { 'action_dispatch.custom' => 'custom' },
  xhr: true,
  as: :json
 (called from block (2 levels) in <class:MicropostsInterfaceTest> at /home/ubuntu/workspace/sample_app/test/integration/microposts_interface_test.rb:25)
  59/59: [==================================================================================================================] 100% Time: 00:00:03, Time: 00:00:03

Finished in 3.52173s
59 tests, 262 assertions, 0 failures, 0 errors, 0 skips