目標
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina
前提
※ ▶◯◯ を選択すると、説明等が出てきますので、
よくわからない場合の参考にしていただければと思います。
deviseで名前ログイン環境構築
controller名はpost(今回は投稿機能のみ)
1、テーブルの作成
Postモデルを追加
$ rails g model Post user:references title:string body:string
実行すると下記のようになり、カラムが追加され保存可能。
class CreatePosts < ActiveRecord::Migration[5.2]
def change
create_table :posts do |t|
t.references :user, foreign_key: true
t.string :title
t.string :body
t.timestamps
end
end
end
$ rails db:migrate
モデルを編集
class Post < ApplicationRecord
belongs_to :user
end
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :posts, dependent: :destroy ←ここを追加
end
解説
コントローラー作成時のuser:referencesにより、
post側にはbelongs_to :userと記述され、1投稿1投稿が誰の投稿か保存できる。
user側にはhas_many :posts, dependent: :destroyと追加することで
1対多の関係を作ることができ、1人のユーザーが多くの投稿ができる。
2、controllerの作成
$ rails g controller posts create new
class PostsController < ApplicationController
before_action :authenticate_user!
def create
@post = Post.new(post_params) # 何を新しく保存するか指定
@post.user_id = current_user.id # 誰が投稿したかを指定
if @post.save # もし保存ができたら
redirect_to new_post_path # 投稿画面に遷移
else # できなければ
render :new # newに遷移
end
end
def new
@post = Post.new
@posts = Post.all
end
private # ストロングパラメーター(予期しない値を変更されてしまう脆弱性を防ぐ機能)
def post_params
params.require(:post).permit(:title, :body) # titleとbodyの変更を許可
end
end
補足
before_action :authenticate_user!と記述することで、
URLをベタ打ちしてもログインしていない限り、new・createアクションを実行できず、
ログイン画面に遷移するようにする。
下記のように変更。
get 'posts/create' ←削除
get 'posts/new' ←削除
resources :posts, only: [:create, :new] ←追加
↓変更後
Rails.application.routes.draw do
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations',
}
root 'homes#top'
get 'mypage', to: 'homes#mypage'
resources :posts, only: [:create, :new] ←追加
end
補足
resourcesはRESTfulなURLであり、getやpatchなどの記述を省略できる。
3、Viewsの変更
app/views/posts/create.html.erb を右クリックで削除。
<h1>Posts#new</h1>
<span>現在ログイン中のユーザー:<%= current_user.name %></span>
<%= form_for(@post, url: posts_path) do |f| %>
<div>
<%= f.label :タイトル %><br>
<%= f.text_field :title, autofocus: true %>
</div>
<div>
<%= f.label :中身 %><br>
<%= f.text_area :body %>
</div>
<div><%= f.submit "投稿する" %></div>
<% end %>
<table>
<thead>
<tr>
<th>投稿者名</th>
<th>タイトル</th>
<th>本文</th>
</tr>
</thead>
<tbody>
<% @posts.each do |post| %>
<tr>
<td><%= post.user.name %></td>
<td><%= post.title %></td>
<td><%= post.body %></td>
</tr>
<% end %>
</tbody>
</table>
補足
form_forヘルパーで投稿機能、eachメソッドで投稿内容取得。
P.S.
twitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork