userのidメソッドが認識されていない話

 

問題

NoMethodError at /articles
undefined method `id' for nil:NilClass

が今回の問題である。user.idのidが何で認識されていないのかが焦点である。

関係するはずのファイルは以下の通りだ。

 

application_controller.rb

class ApplicationController < ActionController::Baseclass ApplicationController <  ActionController::Base before_action :set_current_user
 def set_current_user @current_user = User.find_by(id: session[:user_id])   end
end

 

articles_controller.rb

def create
 @article = Article.new(
  article_params,
  user_id: @current_user.id
 )

 respond_to do |format|
 if @article.save
  format.html { redirect_to @article, notice: 'Article was successfully created.' }
  format.json { render :show, status: :created, location: @article }
 else
  format.html { render :new }
  format.json { render json: @article.errors, status: :unprocessable_entity }
  end
 end
end

 Article.newを作るにあたり、user_idカラムに値を入れたいのだが、idが理解されずつまずいた。

 

やったこと1

そう言えばさっきuser_id作ったけど、どういう状況なのか見た所

f:id:kapiba-ra:20180526162118p:plain

いや、あんたUserモデルにuser_idカラム作ってるやないかーい。

そりゃarticleにuser_id入れられないわな。

とりあえず、userのuser_id消して、articleにuser_id足します。

f:id:kapiba-ra:20180526163250p:plain

でも解消されない。問題はそれだけではないようだ。

 

やったこと2

外で@user定義してやればいいんじゃねというお話。currtent_userをそもそも使わないで、sessionからやってみる。

def create
 @user = User.find_by(id: session[:user_id])
 @article = Article.new(
  article_params,
  user_id: @user.id
 )

 respond_to do |format|
  if @article.save
   format.html { redirect_to @article, notice: 'Article was successfully created.' }
   format.json { render :show, status: :created, location: @article }
  else
   format.html { render :new }
   format.json { render json: @article.errors, status: :unprocessable_entity }
  end
 end
end

 

 

でも相変わらずにidが何か認識されていないみたい。

 

やったこと3

Article.newの外側においておけば反応してくれるんじゃないかなという考え。

 

def create
 @article = Article.new(
 article_params,
)
 @article.user_id = @current_user.id

/ 以下略

 

直んねーwww

 

やったこと4

さっきからidが何か聞かれてるんだからidがわかる形になってないのかと思う。params使ってないよなそう言えば、、そこ直してみよう。

 

(コードはメモし忘れた)

 

でもできないそもそもparamsって、formで入力したデータか、リンクの:idとか取ってくるときしか使わないもんな関係ないよなあ

 

やったこと5

 

@current_userをcurrent_userにすれば良いのではないか。そして、article.newの外に持って来れば良いのではないか。

 

def create
 @article = Article.new(
  article_params
 )
 @article.user_id = current_user.id

/ 以下略

 

できた。やっとできた。

今回の問題になっていたことは

  • 違うテーブルにuser_idを追加していた。
  • @current_userという使い慣れないものを指定していた。
  • 個別でできるか試していないんだからまとめてやろうとしない。

っていうところですね。勉強になりました。

 

補足

 

そのあとで同様のエラーが違う工程で出たから、試しにidがnullのarticlesを全部消したら解決しました。こっちがそもそもの問題になっていた説もあるな。

 

deviseのsignup時に、confirmed_atメソッドがないと怒られた話

今回の問題

railsのdeviseをインストールしたものの、signupできずに困った。

undefined local variable or method `confirmed_at' for #<User:0x007ff3f0c0bb38>
Did you mean? confirmed?

f:id:kapiba-ra:20180525174259p:plain

 

confirmed_atってメソッド知らないんだけど何ですかそれ、って怒られました。あとはconfirmedが何かってのも知ってるか聞かれてる。このあたりをみていこう。

 

試したこと1

qiita.com

 

20180525045855_devise_create_users.rb のコメントアウトをチェックしてみた。

 

20180525045855_devise_create_users.rb

## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable

## Lockable
t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
t.string :unlock_token # Only if unlock strategy is :email or :both
t.datetime :locked_at

 

やっぱりちゃんとコメントアウト解除してある。

migrateしてないのかとrake db:migrateも試してみたけど何の変化もなし。

 

今回は諦め

ググってもこれしかやり方が出てこないからとりあえずメール認証を諦めることにする。だからメール認証に関する部分はコメントアウトしておく。

 

と思ったがいじっていたらあちらこちらでメソッドエラーが出てしまったので、deviseのデフォルトに戻しておくことにした。

 

20180525045855_devise_create_users.rb

# ## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmabl
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at

 

 

models/concern/user.rb

class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :omniauthable, omniauth_providers: [:twitter]
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# :lockable, :timeoutable
end

 

デフォルトにしたら発生したエラー

これで終わろうとしていたのだが、なにやら別のエラーを吐かれてしまった。

undefined local variable or method `pages_show_path' for #<#<Class:0x007fe7b6deb868>:0x007fe7b6de3de8>

f:id:kapiba-ra:20180525184604p:plain

 

pages_show_pathっていうパスがないと言われている。

 

試しに該当の箇所をコメントアウトしてみると、表示できた。

とりあえずコメントアウトしたまま進めていこう。

 

もうちょっとしたらここもみていく。

 

構築の参考にしていたエントリー

qiita.com