Ruby on Rails でのユーザー情報と投稿の紐付けに関して
■前提・実現したいこと
Ruby on Rails で
複数のユーザーが記事を投稿できる簡単なブログを作っています。
誰でもemailとpasswordを使ってログインし、
記事を投稿できるようにしています。
そして今実装したいのは
「記事のページにいくと記事を投稿した人が誰かをemailアドレスで表示する」
ということです。
例えば
Aさんがa@yahoo.co.jpでログインし投稿した記事には
「書いた人:a@yahoo.co.jp」
と表示し、
Bさんがb@yahoo.co.jpでログインし投稿した記事には
「書いた人:b@yahoo.co.jp」
と表示したいです。
userに関してはdeviseを利用しています。
画像で例をあげると、
ログインしてから下のように記事を投稿すると
記事のページではこのように書いた人を表示させたいです。
また編集したときにはemailの表示は変えなくて
いいようにもしたいです。
つまり
Aさんがa@yahoo.co.jpでログインし投稿した記事には
「書いた人:a@yahoo.co.jp」
と表示しますが、この記事をBさんが編集しても
「書いた人:a@yahoo.co.jp」のまま
という感じです。
=================================
これを実装するにあたり
まずpostにhas_many:usersを加えて関連付けし、
記事のデータ(post)に
user_idというカラムを追加し、
これにログインして記事を投稿する人のidを
代入して保存し、viewのhtml.erbの部分で
「投稿者:<% @post.user.email%>」
としようとしましたが上手くいきませんでした。
ログインし、実際に記事を投稿しようとしたときに
以下のようなエラーが出ました。
■発生している問題・エラーメッセージ
■該当のソースコード
コントローラーは下のようになります。
●application_controller.rbに
以下のようにコードを書き加え
before_action :set_current_user, only: [:create]
def set_current_user
@current_user = User.find_by(id: session[:user.id])
end
●posts_controller.rbにはこのように書いています。
class PostsController < ApplicationController
def index
@post = Post.all.order(created_at: 'desc')
end
def show
@post = Post.find_by(params[:id])
@user = User.find_by(id: @post.user_id)
end
def new
@post = Post.new
end
def create
@post = Post.new(
content: params[:content],
user_id: @current_user.id
)
if @post.save
redirect_to root_path
else
render 'new'
end
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
if @post.update(post_params)
redirect_to post_path
else
render 'edit'
end
end
def post_params
params.require(:post).permit(:title, :body)
end
end
●show.html.erbに書いた部分は以下です。
<p>書いた人:<%= @post.user.email %> </p>
●modelのpost.rbも載せておきます。
class Post < ApplicationRecord
validates :title, presence: true
validates :body, presence: true
has_many :users
end
●dbはこのようになっています。
ActiveRecord::Schema.define(version: 20171209035931) do
create_table "posts", force: :cascade do |t|
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
end
create_table "users", force: :cascade 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
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
■試したこと
↓のサイトに書かれている通りにやってみました。
https://qiita.com/you88/items/63ad0b9c07da4323fe26
しかし上手くいかず、色々と調べたり
変数いじったりしてみたのですが解決しません。
■補足情報(言語/FW/ツール等のバージョンなど)
補足というか思ったの事なのですが
エラーのidがnil Classとなっていますが、
そもそも@current_userにログインしている
ユーザーの値が入っていないのではないか
と思っております。
困っています。
よろしくお願いいたします。
==============================
追記
ご返信ありがとうございます。
ご指摘の通りhas_manyは間違っていたと思います。
ありがとうございます。
ですが、ほかの部分でつまっているので
もう少しお力をお貸しいただけたらと思います。
現在このように記事を
投稿しようとしたら
このようなエラーがでるという状況です。
上にも書いたのですが、
コントローラーは
application_controller.rbでは
before_action :set_current_user, only: [:create]
def set_current_user
@current_user = User.find_by(id: session[:user_id])
end
post_controller.rbでは
def create
@post = Post.new(
post_params,
user_id: current_user.id
)
if @post.save
redirect_to root_path
else
render 'new'
end
end
としています。
解決策があれば
教えて戴けたらと思います。
どうかよろしくお願いします。
==================================================
追記2
ありがとうございます。
前者の方で試してみることにしました。
しかし、ログインして
記事を投稿しようとしたところ、
次のようにcurrent_user.idがnilだと
言われてしまいました。
ログインしている状態でしか
投稿できない様にしているので、
ログインしていることは確実なのですが、
なぜこのようになってしまうのでしょうか?
勝手な想像ですが、
gem deviseを利用している場合、
application_controller.rbの
before_action :set_current_user, only: [:create]
def set_current_user
@current_user = User.find_by(id: session[:user_id])
end
という部分が使えないとかいう
ことがあったりするのでしょうか?
何度もすみませんが、
どうぞよろしくお願いいたします。
====================================
追記3
application_controller.rbにて
before_action :set_current_user, only: [:create]
def set_current_user
@current_user = current_user
end
としたところ、記事の投稿でエラーがでることは
なくなりました!
しかし、各記事のページに行くと
となってしまいます。
これはすなわちpostにuser情報が
くっついていないということなんでしょうか?
どうすれば良いのでしょうか...
どうぞよろしくお願いいたします。