ツイートを投稿してタイムラインに表示させ、コメントを投稿、表示させる機能を実装します。
#1.tweetモデルの作成。
$ rails g model tweet
app/model/tweet.rb
class Tweet < ActiveRecord::Base
belongs_to :user
has_many :comments
end
#2.commentモデルの作成。
$ rails g model comment
app/model/comment.rb
class Comment < ActiveRecord::Base
belongs_to :tweet
belongs_to :user
end
*userモデルへも追記します。
app/model/user.rb
class User < ActiveRecord::Base
has_many :tweets
has_many :comments
end
#3.マイグレーションの編集。
db/migrate/...(tweet)
class CreateTweets < ActiveRecord::Migration
def change
create_table :tweets do |t|
t.text :text
t.integer :user_id
t.timestamps null: false
end
end
end
db/migrate/...(comment)
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.integer :user_id
t.integer :tweet_id
t.text :text
t.timestamps null: false
end
end
end
$ bundle exec rake db:migrate
#4.ルートの編集。
config/routes.rb
get "show_tweets" => "tweets#show_tweets"
resources :tweets do
resources :comments, only: [:create, :destroy]
end
#5.コントローラーの編集。
*事前にkaminari のGemをインストールしています。
$ rails g controller tweets
$ rails g controller comments
app/controller/tweets_controller.rb
class TweetsController < ApplicationController
def index
@user = current_user
@search = Tweet.search(params[:q])
@tweets = @search.result.includes(:user).order("created_at DESC").page(params[:page]).per(20)
end
def new
end
def create
Tweet.create(text: tweet_params[:text], user_id: current_user.id)
end
def destroy
tweet = Tweet.find(params[:id])
tweet.destroy if tweet.user_id == current_user.id
end
def edit
@tweet = Tweet.find(params[:id])
end
def update
tweet = Tweet.find(params[:id])
tweet.update(tweet_params) if tweet.user_id == current_user.id.order("created_at DESC").page(params[:page]).per(20)
end
def show
@tweet = Tweet.find(params[:id])
@comments = @tweet.comments.includes(:user)
end
def show_tweets
@user = current_user
@tweets = Tweet.where(user_id: @user.id).all.order("created_at DESC").page(params[:page]).per(20)
end
private
def tweet_params
params.permit(:text)
end
end
app/controllers/users_controller.rb
class UsersController < ApplicationController
def users_tweets
@user = User.find(params[:id])
@tweets = Tweet.where(user_id: @user.id).all.order("created_at DESC").page(params[:page]).per(20)
end
end
app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
@comment = Comment.create(text: comment_params[:text], tweet_id: comment_params[:tweet_id], user_id: current_user.id)
redirect_to "/tweets/#{@comment.tweet.id}"
end
private
def comment_params
params.permit(:text, :tweet_id)
end
end
#6.ビューファイルの編集。
app/views/tweets/index.html.erb
<h2>ツイート検索</h2>
<%= link_to 'ツイートを投稿する', new_tweet_path, {class: 'btn btn-primary withripple' }%>
<%= link_to '自分のツイート一覧へ', show_tweets_path, {class: 'btn btn-primary withripple' }%>
<% @tweets.each do |tweet| %>
<div class="contents row" >
<div class="name3">投稿者:<%= link_to tweet.user.username, user_path(tweet.user), method: :get %></div>
<div class="name2">投稿日時:<%= tweet.created_at.strftime("%Y-%m-%d %H:%M:%S") %></div>
<div class="name2"><%= link_to '詳細', tweet_path(tweet), method: :get %></div>
<% if user_signed_in? && current_user.id == tweet.user_id %>
<div class="name2">
<%= link_to '編集', edit_tweet_path(tweet), method: :get %>
</div>
<div class="name2">
<%= link_to '削除', "/tweets/#{tweet.id}", method: :delete %>
</div>
<% end %>
<div class="name3"><%= simple_format(tweet.text) %></div>
</div>
<% end %>
<%= paginate(@tweets) %>
</div>
app/views/tweets/new.html.erb
<div class="contents row">
<%= form_tag('/tweets', method: :post) do %>
<h2>
投稿する
</h2>
<textarea cols="30" name="text" placeholder="text" rows="10"></textarea>
<br/>
<input type="submit" value="投稿する">
<% end %>
</div>
app/views/tweets/create.html.erb
<div class="contents row">
<div class="success">
<h2>
投稿が完了しました。
</h2>
<%= link_to '投稿一覧へ戻る', tweets_path, {class: 'btn btn-primary withripple' }%>
</div>
</div>
app/views/tweets/destroy.html.erb
<div class="contents row">
<div class="success">
<h2>
削除が完了しました。
</h2>
<%= link_to '投稿一覧へ戻る', tweets_path, {class: 'btn btn-primary withripple' }%>
</div>
</div>
app/views/tweets/edit.html.erb
<div class="contents row">
<%= form_tag("/tweets/#{@tweet.id}", method: :patch ) do %>
<h2>
編集する
</h2>
<textarea cols="30" name="text" placeholder="text" rows="10"><%= @tweet.text %></textarea>
<br/>
<input type="submit" value="変更する">
<% end %>
</div>
app/views/tweets/update.html.erb
<div class="contents row">
<div class="success">
<h2>
更新が完了しました。
</h2>
<%= link_to '投稿一覧へ戻る', tweets_path, {class: 'btn btn-primary withripple' }%>
</div>
</div>
app/views/tweets/show.html.erb
<h2>投稿</h2>
<div class="contents row" >
<div class="name3">投稿者:<%= link_to @tweet.user.username, user_path(@tweet.user), method: :get %></div>
<div class="name2">投稿日時:<%= @tweet.created_at.strftime("%Y-%m-%d %H:%M:%S") %></div>
<% if user_signed_in? && current_user.id == @tweet.user_id %>
<div class="name2">
<%= link_to '編集', edit_tweet_path(@tweet), method: :get %>
</div>
<div class="name2">
<%= link_to '削除', "/tweets/#{@tweet.id}", method: :delete %>
</div>
<% end %>
<div class="name3"><%= simple_format(@tweet.text) %></div>
</div>
<div class="contents row" >
<h2>コメント一覧</h2>
<% if @comments %>
<% @comments.each do |comment| %>
<div class="name2">投稿者:<%= link_to comment.user.username, "/users/#{comment.user_id}" %> 投稿日時:<%= comment.created_at.strftime("%Y-%m-%d %H:%M:%S") %></div>
<div class="name2"><%= comment.text %></div>
<% end %>
<% end %>
<br/>
<% if current_user %>
<%= form_tag("/tweets/#{@tweet.id}/comments", method: :post) do %>
<textarea cols="30" name="text" placeholder="コメントする" rows="2"></textarea>
<br/>
<input type="submit" value="コメントの投稿">
<% end %>
<% end %>
</div>
app/views/tweets/show_tweets.html.erb
<h2>自分のツイート一覧</h2>
<%= link_to 'ツイートを投稿する', new_tweet_path, {class: 'btn btn-primary withripple' }%>
<% @tweets.each do |tweet| %>
<div class="contents row" >
<div class="name3">投稿者:<%= link_to tweet.user.username, user_path(tweet.user), method: :get %></div>
<div class="name2">投稿日時:<%= tweet.created_at.strftime("%Y-%m-%d %H:%M:%S") %></div>
<div class="name2"><%= link_to '詳細', tweet_path(tweet), method: :get %></div>
<% if user_signed_in? && current_user.id == tweet.user_id %>
<div class="name2">
<%= link_to '編集', edit_tweet_path(tweet), method: :get %>
</div>
<div class="name2">
<%= link_to '削除', "/tweets/#{tweet.id}", method: :delete %>
</div>
<% end %>
<div class="name3"><%= simple_format(tweet.text) %></div>
</div>
<% end %>
<%= paginate(@tweets) %>
</div>
app/views/users/users_tweets.html.erb
<h2><%= @user.username %>のツイート一覧</h2>
<%= link_to 'ツイートを投稿する', new_tweet_path, {class: 'btn btn-primary withripple' }%>
<% @tweets.each do |tweet| %>
<div class="contents row" >
<div class="name3">投稿者:<%= link_to tweet.user.username, user_path(tweet.user), method: :get %></div>
<div class="name2">投稿日時:<%= tweet.created_at.strftime("%Y-%m-%d %H:%M:%S") %></div>
<div class="name2"><%= link_to '詳細', tweet_path(tweet), method: :get %></div>
<% if user_signed_in? && current_user.id == tweet.user_id %>
<div class="name2">
<%= link_to '編集', edit_tweet_path(tweet), method: :get %>
</div>
<div class="name2">
<%= link_to '削除', "/tweets/#{tweet.id}", method: :delete %>
</div>
<% end %>
<div class="name3"><%= simple_format(tweet.text) %></div>
</div>
<% end %>
<%= paginate(@tweets) %>
</div>