-定時日記交換システム-
共同で作成しているrailsのプロジェクト
自分の発見や行動を
好きな時間に記録
決まった時間に確認
## 使い方
- git clone
- bundle install
- yarn install
- rails db:migrate
- rails s
git clone
bundle install
yarn install
rails db:migrate
rails s
twitterもどきだが少し違う
#どんな設計にするのか ・ユーザー →投稿できる →投稿に対してコメントを残すことができる
・投稿 →内容のみ
・コメント →内容のみ
$ rails new twitter
$ cd twitter
今回は投稿者用のUserモデルと投稿用のPostモデルを作る
ログインができるようにdeviseを導入します。 Gemfileに以下を追加
gem 'devise'
deviseを使える環境を整えていきます。
$ bundle install
$ rails g devise:install
$ rails g devise user
$ rails g devise:views
投稿用のPostモデルを作成します。ここには投稿内容contentと、誰が投稿したのかというuser_idが入るようにします。
$ rails g model post content:string user:references
$ rails db:migrate
今作ったUserモデルとPostモデルは1対多の関係です。 ユーザーそれぞれはたくさんの投稿ができ、投稿それぞれは1人のユーザーによって書かれたものであるというようなイメージです。
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :posts, dependent: :destroy
endhas_many :posts の後に今回はdependent: :destroyをつけました。これはpostがuserに依存している。ここでは、もしユーザーがデータベースから削除されてしまった場合にユーザーがした投稿も全て消えるようになります。
モデルの作成時にuser:referencesをつけたのですでにbelongs_to :userが書かれています。
class Post < ApplicationRecord
belongs_to :user
endユーザーの一覧ページと詳細ページがあることを考慮して、indexアクションとshowアクションを定義します。
$ rails g controller users index show
投稿も同様にindexアクションとshowアクションを定義します。(createアクションもあるが、ビューが存在しないのでここでは書かない)
$ rails g controller posts index show
ルーティングを考えていきます。
・投稿の一覧と詳細が見れる ・投稿することができる ・ユーザーの一覧と詳細が見れる ことから以下のようなルーティングにします。 ####routes.rb
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:index, :show]
resources :posts, only: [:index, :show, :create]
root 'posts#index'
endposts_controllerを以下のように変更しよう。
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:show, :create]
def index
@posts = Post.all
@post = Post.new
end
def show
@post = Post.find(params[:id])
end
def create
@post = Post.new(post_params)
@post.user_id = current_user.id
if @post.save
redirect_back(fallback_location: root_path)
else
redirect_back(fallback_location: root_path)
end
end
private
def post_params
params.require(:post).permit(:content)
end
endログインしていないユーザーはshow, createは実行できないようになりました。
次はビューを作っていきます。
<h1>コメントサンプル</h1>
<% if user_signed_in? %>
<%= link_to "ログアウト", destroy_user_session_path, :method => :delete %>
<%= link_to "マイページへ", user_path(current_user.id) %>
<h2>投稿する</h2>
<%= form_for @post do |f| %>
<%= f.text_field :content %>
<%= f.submit %>
<% end %>
<hr>
<h2>投稿一覧</h2>
<% @posts.each do |post| %>
<a href="/users/<%= post.user.id %>"><%= post.user.email %></a>
<p><a href="/posts/<%= post.id %>"><%= post.content %></a></p>
<% end %>
<% else %>
<%= link_to "ユーザー登録", new_user_registration_path %>
<%= link_to "ログイン", new_user_session_path %>
<% end %><h1>投稿詳細ページ</h1>
<h3><%= @post.user.email %></h3>
<h3><%= @post.content %></h3>
<%= link_to "ホームへ戻る", posts_path %>class UsersController < ApplicationController
def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
end<h1>ユーザー一覧</h1>
<% @users.each do |user| %>
<a href="/users/<%= user.id %>"><%= user.email %></a>
<hr>
<% end %>
<%= link_to "ホームへ戻る", posts_path %><h1>ユーザー詳細ページ</h1>
<h3><%= @user.email %></h3>
<h2>投稿内容</h2>
<% @user.posts.each do |post| %>
<a href="/posts/<%= post.id %>"><%= post.content %></a>
<hr>
<% end %>
<%= link_to "ユーザー一覧へ", users_path %>
<%= link_to "ホームへ戻る", posts_path %>これからやっとコメント機能を実装していきます。 コメント機能は、誰がどの投稿に対してコメントをしたのかという情報をCommentテーブルというUserテーブルとPostテーブルの中間テーブルに格納していきます。
$ rails g model comment content:string user:references post:references
$ rails db:migrate
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
has_many :comments
endclass Post < ApplicationRecord
belongs_to :user
has_many :comments
end$ rails g controller comments
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:index, :show]
resources :posts, only: [:index, :show, :create] do
resources :comments, only: [:create]
end
root 'posts#index'
endclass CommentsController < ApplicationController
def create
@comment = Comment.new(comment_params)
@comment.user_id = current_user.id
if @comment.save
redirect_back(fallback_location: root_path)
else
redirect_back(fallback_location: root_path)
end
end
private
def comment_params
params.require(:comment).permit(:content, :post_id) #追加
end
endclass PostsController < ApplicationController
before_action :authenticate_user!, only: [:show, :create]
def index
@posts = Post.all
@post = Post.new
end
def show
@post = Post.find(params[:id])
@comments = @post.comments
@comment = Comment.new
end
def create
@post = Post.new(post_params)
@post.user_id = current_user.id
if @post.save
redirect_back(fallback_location: root_path)
else
redirect_back(fallback_location: root_path)
end
end
private
def post_params
params.require(:post).permit(:content)
end
endその投稿に対するコメントの一覧と、コメントができるようになります
<h1>投稿詳細ページ</h1>
<h3><%= @post.user.email %></h3>
<h3><%= @post.content %></h3>
<h2>コメント一覧</h2>
<% @comments.each do |c| %>
<div>
<a href="/users/<%= @post.user.id %>"><%= c.user.email %></a>
<%= c.content %>
<hr>
</div>
<% end %>
<%= form_for [@post, @comment] do |f| %>
<%= f.text_field :content %>
<%= f.hidden_field :post_id, value: @post.id %> #追加
<br>
<%= f.submit 'コメントする', class: "btn btn-primary" %>
<% end %>
<%= link_to "ホームへ戻る", root_path %>
<%= link_to "ホームへ戻る", posts_path %>これでユーザーが投稿に対してコメントができる

