Day15です!
いよいよ終盤!明日までに終わらせたい!
今日もがんばっていきましょー!
読んでいただいている方、いつもありがとうございます!
初心者なもので、たまに間違った内容もあるかと思います。
その際にはコメントやTwitterでご指摘いただけると幸いです!
[Day15]第十三章13.1〜13.5作業ログ
今回は投稿機能を追加していきます
前回までのチュートリアルで、ユーザー の作成とか削除とかに関する実装は完了しました。
今回はログインしているユーザーから、投稿ができるようにしていきます。
ここでは、めっちゃくちゃ序盤にやった、ブログの投稿機能に似た箇所も登場するので、楽しみです。
Micropostモデルの作成
とりあえずは、投稿を保存するためのMicropostモデルを作成していきます。
1つ注意点があって、投稿はどのユーザーがしたものなのかを紐づけておきたいこと。
そのために、ちょびちょび設定があります。
rails generate model Micropost content:text user:references
class Micropost < ApplicationRecord
belongs_to :user
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 140 }
end
class CreateMicroposts < ActiveRecord::Migration[5.0]
def change
create_table :microposts do |t|
t.text :content
t.references :user, foreign_key: true
t.timestamps
end
add_index :microposts, [:user_id, :created_at]
end
end
rails db:migrate
User/Micropostの関連付け
さっきのbelongs_toとここで設定するhas_manyでUser/Micropostを関連付けます。
class User < ApplicationRecord
has_many :microposts
...
end
これによって、ユーザーと投稿が関連付けられました。
belongs_to/has_many関連付けを使うことで、次に示すようなメソッドをRailsで使えるようになります。
Micropostを降順にする
今のままだと、投稿は古い順版に表示されます。
ツイッターやブログみたいに新しい投稿がはじめに表示されるようにします。
class Micropost < ApplicationRecord
belongs_to :user
default_scope -> { order(created_at: :desc) }
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 140 }
end
->はラムダ式と言うみたいです。むずかしめらしいのでまた今度理解しよう。
ユーザーが削除されたら、そのユーザーの投稿も消えるように
ユーザーが削除されたときに、そのユーザーに紐付いた (そのユーザーが投稿した) マイクロポストも一緒に削除されるようにしたいです。
データベースの節約やセキュリティ面で大事。
こんな感じで依存関係を示してあげると実装できるそう。
class User < ApplicationRecord
has_many :microposts, dependent: :destroy
...
end
投稿を表示していく
showアクションで投稿を表示できるようにします。
<% provide(:title, @user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for @user %>
<%= @user.name %>
</h1>
</section>
</aside>
<div class="col-md-8">
<% if @user.microposts.any? %>
<h3>Microposts (<%= @user.microposts.count %>)</h3>
<ol class="microposts">
<%= render @microposts %>
</ol>
<%= will_paginate @microposts %>
<% end %>
</div>
</div>
ここで、マイクロソフトを表示するパーシャルはこんな感じ。
<li id="micropost-<%= micropost.id %>">
<%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
<span class="user"><%= link_to micropost.user.name, micropost.user %></span>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
</li>
あと、ページネーションもちょっと変えてあげないとだめです。
class UsersController < ApplicationController
...
def show
@user = User.find(params[:id])
@microposts = @user.microposts.paginate(page: params[:page])
end
...
end
あとCSSもチュートリアルにあるように調節しました。
実際に投稿機能を実装
ここまでで投稿の表示ができるようになりました。
ここからは、投稿機能をつけていきます。
今回はビューは必要なく、createとdestroyアクションだけでOKです。
まずはルーティング。
Rails.application.routes.draw do
root 'static_pages#home'
get '/help', to: 'static_pages#help'
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
get '/signup', to: 'users#new'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :microposts, only: [:create, :destroy]
end
これからコントローラーの設定をしていきます。
投稿するのは、ログインユーザーに限定したいです。
この設定は、users_controller.rbと同じなので、この中身をapplication_controller.rbに移すことで、microposts_controller.rbからも使えるようになります。
class MicropostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
def create
end
def destroy
end
end
投稿機能はこんな感じで実装。
class MicropostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
flash[:success] = "Micropost created!"
redirect_to root_url
else
render 'static_pages/home'
end
end
def destroy
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
end
削除機能の実装
class MicropostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
...
def destroy
@micropost.destroy
flash[:success] = "Micropost deleted"
redirect_to request.referrer || root_url
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
def correct_user
@micropost = current_user.microposts.find_by(id: params[:id])
redirect_to root_url if @micropost.nil?
end
end
他にもいろいろと設定がありましたが、ここでは割愛します!
今回はちょっと雑ですが、こんな感じで終了!
メモ
個別のテストを実行するコマンド
rails test test/models/micropost_test.rb
SQLインジェクション
SQLインジェクション(英: SQL Injection)とは、アプリケーションのセキュリティ上の不備を意図的に利用し、アプリケーションが想定しないSQL文を実行させることにより、データベースシステムを不正に操作する攻撃方法のこと。また、その攻撃を可能とする脆弱性のことである。
[Day15]まとめ
- 学習範囲:13.1〜13.5
- 学習時間:4時間10分
- 総学習時間:63時間10分
- 反省点:この記事が雑。まとめ直すのに時間がかかり過ぎな気がする。あんまり時間的コスパが良くない。
- 備考:明日で1周終わらせたい。
読んでいただいている方、いつもありがとうございます!
初心者なもので、たまに間違った内容もあるかと思います。
その際にはコメントやTwitterでご指摘いただけると幸いです!
コメントを残す