技術ブログっぽいなにか

Ruby・Railsメインでいろんなこと書きます

【Active Record】値が保存できなかった

メッセージがお気に入りされたらFavoriteテーブルにそのメッセージのidが保存されるようにしたかった
けど、なぜか保存されなかった。

関係ありそうな場所

Controller

class FavoriteController < ApplicationController

  def create
    @user_id = current_user.id
    @favorite = Favorite.new(message_id: params[:id], user_id: current_user.id)


    if @favorite.save
      redirect_to home_path, success: 'お気に入り登録しました!'
    else
      redirect_to home_path, danger: 'お気に入り登録ができませんでした'
    end
  end

  def destroy
    @favorite = Favorite.find(params[:id])
    if @favorite.destroy
      redirect_to home_path
    end
  end

end

createメソッドがうまくいってないっぽい。

原因

カラム名が複数形になっていた。
他テーブルの主キーとジョインするカラムは テーブル名(単数系)_idじゃないとダメらしい
参考:データベースオブジェクトの命名規約 - Qiita

ActiveRecord::Schema.define(version: 20171231015724) do

  create_table "favorites", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer  "user_id",    null: false
    t.integer  "messages_id", null: false  #<=ここ
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["message_id"], name: "index_favorites_on_message_id", using: :btree
    t.index ["user_id"], name: "index_favorites_on_user_id", using: :btree
  end

  create_table "messages", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer  "user_id"
    t.string   "contents"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    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",                          null: false
    t.datetime "updated_at",                          null: false
    t.index ["email"], name: "index_users_on_email", unique: true, using: :btree
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
  end

end

解決策

$ rails g migration RenameMessagesIdColumnToFavoritesマイグレーションファイルを作ってmigrateする。

class RenameMessagesIdColumnToFavorites < ActiveRecord::Migration[5.0]
  def change
    rename_column :favorites, :messages_id, :message_id
  end
end
$ rails db:migrate

終わり。

Rails命名規則、あんまり覚えていないせいでいちいちググっているので、ちゃんとまとめたい…

参考

qiita.com