0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rails 入力した値をその通り保存できなかった時に、ログを確認して学んだこと!

Last updated at Posted at 2023-12-02

バージョン

  • ruby 3.2.2
  • Rails 6.1.7.6

スクールの課題でタスク管理アプリを作成中、先にnamecontentのカラムを作ってあり、後で、timelimit(終了期限)のカラムを追加した。後からカラムを追加すると、既に保存してあるデータベースについては、後から追加したカラムの値がnilとなってしまいエラーになってしまうので、デフォルト値を設定した。

しかし、新規投稿しても、終了期限が、デフォルト値で設定してある「今日」になって登録されてしまう!!なぜだ!!

スクリーンショット 2023-12-01 10.32.13.png

schema.rb の中身はこんな感じ↓

schema.rb
  create_table "tasks", force: :cascade do |t|
    t.string "name", null: false
    t.text "content", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.date "timelimit", default: -> { "CURRENT_DATE" }, null: false
  end
end

このエラー回避のため、コールバックでset_default_timelimitメソッドを追加していたので
binding.irbを入れて試してみる!

app/models/task.rb
class Task < ApplicationRecord
  before_create :set_default_timelimit
  validates :name, :content, presence: true
  validates :name, length: {maximum: 100}
  validates :content, length: {maximum: 1000}

  private

  def set_default_timelimit
    binding.irb
    self.timelimit ||= Date.today
  end
end

スクリーンショット 2023-12-02 12.10.26.png

Unpermitted parameter: :timelimit というエラー表示があり、
また、selfの中をチェックしてみると、
timelimitnilになっている!!なぜだなぜだ!!

app/controllers/tasks_controller.rb
class TasksController < ApplicationController

  # 省略

  def new
    @task = Task.new
  end

  def create
    @task = Task.new(task_params)
    if @task.save
      redirect_to task_path(@task.id), notice: "投稿を作成しました!"
    else
      render :new
    end
  end

   # 省略
  
  private

  def task_params
    params.require(:task).permit(:name, :content)
  end

end

問題は、このtask_paramsメソッド!

params.require(:task).permit(:name, :content)

この中に、timelimitを入れ忘れていたために、Unpermitted parameter: :timelimit(許可されていないパラメーター、の意味)が表示された。binding.irbで確認した時timelimitnilになっているのは、パラメーターが許可されてなかったために、入力された終了期限はtimelimitに値として入ることはできず、初期値として設定してある今日の日付がtimelimitの値として保存されてしまうのでした。(schema.rb参照)

ちなみに豆知識を教えてもらった!
IDnilとなっているのは、このbinding.irbによってデータベースに保存される直前で止まっているから!
データベースに保存されて初めてIDが付与され保存されるので、データベースに保存される直前ではnilになっているとのこと。おーーなるほど、面白い!

そして、後から判明したことがあった!
timelimitに値が入らなかった時、色々試すために下記のように

app/models/task.rb
class Task < ApplicationRecord
  before_create :set_default_timelimit
  
  #省略
  
  private

  def set_default_timelimit
    self.timelimit ||= Date.today
  end
end

app/models/task.rbの中に、set_default_timelimitを定義したけれど、結局は、task_paramsメソッドに、timelimitを入れ忘れていたことがtimelimitに値が入らない要因だったわけだから、このset_default_timelimitメソッドは消してもうまく動きました!

モヤモヤ理解だったselfについて理解できた!

でもでも、不要だったset_default_timelimitを定義したおかげで、ずっとモヤモヤしてた  selfについて理解を深めることができてよかった!!
selfって、よく「それ自身」とか「そのもの」とかって説明されているけど、それ自身って何よ?っていう感じだった!スクリーンショット 2023-12-02 10.43.09.png
でも、実際にこうやってselfの中身を見てみると、nameは「mama」、contentは「写真購入」とデータが入っているのがわかり、ほんとだ〜それ自身だ〜そのものになってる〜、ととても感動しました!良い収穫になり、とても良かったで〜す!!😆

bindingでデータの中身を確認したりログを確認しながら勉強をしていくととっても面白いなーと強く実感することができました!!😃

本日は以上!お疲れ様でした!

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?