投稿機能の実装
*この記事は技術や知識の共有目的ではなく、完全に自己満足のアウトプット用です。
<開発環境>
- ruby 2.6.3
- Rails 5.1.6
- AWS Cloud9
- GitHub
- Heroku(予定)
- sqlite3(develop環境)
今回は投稿、投稿編集、投稿削除の基本的な動作を実装しました。
投稿
postモデルの作成
rails g model Posts content:text user:reference image:string
postテーブルを作るときにreferenceを用いることでテーブルにuser_idカラムが自動で生成されます。
また、foreign_key: trueを記載することで外部キー制約をつけることができます。
モデルの関連付け
投稿の編集、削除機能を作る事前準備をします。
Postモデルに
belongs_to :user
Userモデルに
has_many :posts
これでモデルの関連付けをし、Railsは参照先のデータを取得したり削除できるメソッドを追加してくれます。
マイグレーション
rails db:migrate
コントローラーの作成
rails g controller posts new
ルーティングに
resources :posts
を追加する。
class PostsController < ApplicationController
before_action :ensure_correct_user, {only: [:edit, :update, :destroy]}
def new
@post = Post.new
end
def create
@post = current_user.posts.new(post_params)
@post.save
flash[:notice] = "投稿に成功しました"
redirect_to user_path(current_user.id)
end
def show
@post = Post.find(id: params[:id])
end
def edit
@post = Post.find_by(id: params[:id])
end
def update
@post = Post.find_by(id: params[:id])
@post.image = params[:image]
@post.content = params[:content]
@post.update(post_params)
redirect_to user_path(current_user.id)
end
def destroy
@post = Post.find_by(id: params[:id])
@post.destroy(post_params)
redirect_to user_path(current_user.id)
end
def ensure_correct_user
@post = Post.find_by(id: params[:id])
if current_user.id != @post.user_id
flash[:notice] = "権限がありません"
redirect_to user_path(current_user.id)
end
end
private
def post_params
params.require(:post).permit(:image, :content)
end
end
ensure_correct_userメソッドを追加することで、ログイン中のユーザー以外が自分の投稿を編集、削除することを防ぐようにしています。(viewの設定だけではurlから直接編集ページに飛べてしまう。)
これでコントローラーの設定は完了です。
viewを整える
今回はTwiiterを参考にして、マイページに投稿画面、投稿一覧画面を載せました。
show.html.erb
<div class="user-show-wrapper">
<div class="container">
<div class="row">
<div class="col-md-3 text-center">
<section class="user_info">
<h1>
<%= @user.name %>
</h1>
<%= form_for @post do |f| %>
<div class="field-image">
<%= f.label :image, class: "white" %>
<%= f.file_field :image%>
</div>
<div class="form-group">
<%= f.label :content, class: "white" %>
<%= f.text_area :content, class: 'form-control' %>
</div>
<%= f.submit '投稿', class: 'btn btn-black btn-block' %>
<% end %>
</section>
</div>
<div class="col-md-6">
<div class="post-index-wrapper">
<div class="container">
<div class="col-md-6">
<% @posts.each do |post| %>
<div class="post-index-single">
<h2 class="post-author">
<%= post.user.name %>
</h2>
<%= image_tag post.image.url if post.image? %>
<p class="post-text">
<%= post.content %>
</p>
<% if post.user_id == current_user.id && user_signed_in? %>
<%= link_to '編集', edit_post_path, class: 'btn btn-default' %>
<%= link_to '削除', post_path, method: :delete, class: 'btn btn-default' %>
<% end %>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
左側の投稿フォームはstickyを用いることでスクロールしてもそのまま固定されるようにしています。
custom.css
.col-md-3{
position: -webkit-sticky;
position: sticky;
top: 60px;
}
これで投稿機能は完成です!