#はじめに
この記事は、railsチュートリアル第十二章の行程を復習しやすいように要約したものとなっています。
##ユーザーのマイクロポスト
この章では短いメッセージを投稿できるようにするためのリソースマイクロポストを追加していく。
###Micropostモデル
はじめにUserモデルの関連付けを含むMicropostモデル
を生成する。
Micropostモデル
は、マイクロポストの内容を保存する content属性
と、特定のユーザーとマイクロポストを関連付ける user_id属性
の2つの属性だけを持つ。
$ rails generate model Micropost content:text user:references
ある程度の量のテキストを格納する場合はtext型が望ましいのでcontentにはtext型をあてている。
上記のコマンドを実行すると Micropostモデル
が生成され、ユーザーと1対1の関係であることを表すbelongs_to
のコードも追加されている。
これは user:references
という引数を含めたことにより、自動的にインデックスと外部キー参照付きの user_idカラム
が追加され、UserとMicropostを関連付けする下準備をしてくれるから。
class Micropost < ApplicationRecord
belongs_to :user
end
またUserモデルのときと同じで、Micropostモデルのマイグレーションファイルでもt.timestamps
という行 (マジックカラム) が自動的に生成されている。
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
上のファイルではuser_idとcreated_atカラムにインデックスが付与されている。
こうすることで、user_idに関連付けられたすべてのマイクロポストを作成時刻の逆順で取り出しやすくなる。
ここでいつも通りマイグレーションで、データベースを更新しておく。
###Micropostのバリデーション
以下のようにバリデーションで存在性、最大文字を検証する。
class Micropost < ApplicationRecord
belongs_to :user
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 140 }
end
###User/Micropostの関連付け
Webアプリケーション用のデータモデルを構築するにあたって、個々のモデル間での関連付けを十分考えておくことが重要となる。
今回の場合は、それぞれのマイクロポストは1人のユーザーと関連付けられ、それぞれのユーザーは (潜在的に) 複数のマイクロポストと関連付けられる。
user/micropost関連メソッドのまとめは以下のようになる。
メソッド | 用途 |
---|---|
micropost.user | Micropostに紐付いたUserオブジェクトを返す |
user.microposts | Userのマイクロポストの集合をかえす |
user.microposts.create(arg) | userに紐付いたマイクロポストを作成する |
user.microposts.create!(arg) | userに紐付いたマイクロポストを作成する (失敗時に例外を発生) |
user.microposts.build(arg) | userに紐付いた新しいMicropostオブジェクトを返す |
user.microposts.find_by(id: 1) | userに紐付いていて、idが1であるマイクロポストを検索する |
@user.microposts.build
のようなコードを使うためには、 UserモデルとMicropostモデルをそれぞれ更新して、関連付ける必要がある。
class Micropost < ApplicationRecord
#マイクロポストがユーザーに所属する関連付け
belongs_to :user
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 140 }
end
class User < ApplicationRecord
#ユーザーがマイクロポストを複数所有する (has_many) 関連付け
has_many :microposts
.
.
.
end
##マイクロポストを改良する
この項では、具体的には、ユーザーのマイクロポストを特定の順序で取得できるようにしたり、マイクロポストをユーザーに依存させて、ユーザーが削除されたらマイクロポストも自動的に削除されるようにしていく。
###デフォルトのスコープ
user.micropostsメソッド
はデフォルトでは読み出しの順序に対して何も保証しないが、ブログやTwitterの慣習に従って、作成時間の逆順、つまり最も新しいマイクロポストを最初に表示するように改良する。
これを実装するためには、default scope
というテクニックを使用する。
投稿はSQL文で、
order('created_at DESC')
を引数に与えたい。
よって以下のようになる。
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
###Dependent: destroy
サイト管理者はユーザーを破棄する権限を持つ。ユーザーが破棄された場合、ユーザーのマイクロポストも同様に破棄されるようにしたい。
この振る舞いは、has_manyメソッド
にオプションを渡してあげることで実装できる。
class User < ApplicationRecord
has_many :microposts, dependent: :destroy
.
.
.
end
dependent: :destroy
というオプションを使うと、ユーザーが削除されたときに、そのユーザーに紐付いた (そのユーザーが投稿した) マイクロポストも一緒に削除されるようになる。
##マイクロポストを表示する
Web経由でマイクロポストを作成する方法は現時点ではないが、ここでは、Twitterのような独立したマイクロポストのindexページは作らずに、ユーザーのshowページで直接マイクロポストを表示させることにする。
###マイクロポストの描画
ここで、ユーザーのプロフィール画面 (show.html.erb) でそのユーザーのマイクロポストを表示させたり、これまでに投稿した総数も表示させたりしていく。
まずは、Micropostのコントローラとビューを作成するために、コントローラを生成する。
$ rails generate controller Microposts
以前は_user.html.erbパーシャルを使って自動的に@users変数内のそれぞれのユーザーを出力していた。
これを参考に、_micropost.html.erbパーシャルを使ってマイクロポストのコレクションを表示しようとすると、次のようになる。
<ol class="microposts">
<%= render @microposts %>
</ol>
よって対応するパーシャルを以下に示す。
<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>
上記では一度にすべてのマイクロポストが表示されてしまう潜在的問題に対処している。
前回のユーザー一覧では
<%= will_paginate %>
のようにコードは引数なしで動作していた。
これはwill_paginateが、Usersコントローラのコンテキストにおいて、@usersインスタンス変数が存在していることを前提としているためとなる。
このインスタンス変数はActiveRecord::Relationクラス
のインスタンスで、今回の場合はUsersコントローラのコンテキストからマイクロポストをページネーションしたいため (つまりコンテキストが異なるため)、明示的に@microposts変数をwill_paginate
に渡す必要がある。
したがって、そのようなインスタンス変数をUsersコントローラの showアクション
で定義しなければならない。
class UsersController < ApplicationController
.
.
.
def show
@user = User.find(params[:id])
#追加
@microposts = @user.microposts.paginate(page: params[:page])
end
.
.
.
end
###マイクロポストの投稿数
投稿数の表示はcountメソッドを使うことで可能となる。
user.microposts.count
以上のことを踏まえてプロフィール画面にマイクロポストを表示させてみる。
<% 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>
###マイクロポストのサンプル
現時点ではマイクロポストがない状態なので、サンプルを追加する。
すべてのユーザーにマイクロポストを追加しようとすると時間が掛かり過ぎるので、takeメソッド
を使って最初の6人だけに追加することにする。
User.order(:created_at).take(6)
この6人については、1ページの表示限界数 (30) を越えさせるために、それぞれ50個分のマイクロポストを追加するようにする。
.
.
.
users = User.order(:created_at).take(6)
50.times do
content = Faker::Lorem.sentence(5)
users.each { |user| user.microposts.create!(content: content) }
end
$ rails db:migrate:reset
$ rails db:seed
このコマンドをうち、railsサーバーを再起動するとプロフィールにマイクロポストのサンプルが表示される。
ここに CSSを加えてスタイルを整える必要があるが、ここでは省略。
##マイクロポストを操作する
データモデリングとマイクロポスト表示テンプレートの両方が完成したので、次はWeb経由でそれらを作成するためのインターフェイスを整えていく。
従来のRails開発の慣習と異なり、Micropostsリソースへのインターフェイスは、主にプロフィールページとHomeページのコントローラを経由して実行されるから、Micropostsコントローラにはnew
やedit
のようなアクションは不要でcreate
とdestroy
があれば十分ということになる。
したがって、Micropostsのリソースは以下になる。
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
HTTPリクエスト | URL | アクション | 名前付きルート |
---|---|---|---|
POST | /microposts | create | microposts_path |
DELETE | /microposts/1 | destroy | micropost_path(micropost) |
###マイクロポストのアクセス制御
関連付けられたユーザーを通してマイクロポストにアクセスするので、createアクションやdestroyアクションを利用するユーザーは、ログイン済みでなければいけない。
以前の章では、beforeフィルターの logged_in_userメソッド
を使って、ログインを要求した。
あのときは Usersコントローラ
内にこのメソッドがあったので、beforeフィルターで指定していたが、このメソッドは Micropostsコントローラ
でも必要となるので、このメソッドをApplicationコントローラ
に移す。
ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include SessionsHelper
private
# ユーザーのログインを確認する
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
end
コードが重複しないよう、このときUsersコントローラからlogged_in_userを削除しておく。
###マイクロポストを作成する
logged_in_userメソッド
により、createアクション
や destroyアクション
に対するアクセス制限が、beforeフィルターで簡単に実装できるようになった。
createアクション
を定義していく。
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
上記ではmicropost_params
でStrong Parametersを使っていることにより、マイクロポストのcontent属性だけがWeb経由で変更可能になっている。
次にマイクロポスト作成フォームを構築するために、サイト訪問者がログインしているかどうかに応じて異なるHTMLを提供するコードを使う。
#追加
<% if logged_in? %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<section class="micropost_form">
<%= render 'shared/micropost_form' %>
</section>
</aside>
</div>
<% else %>
<div class="center jumbotron">
<h1>Welcome to the Sample App</h1>
<h2>
This is the home page for the
<a href="https://railstutorial.jp/">Ruby on Rails Tutorial</a>
sample application.
</h2>
<%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %>
</div>
<%= link_to image_tag("rails.png", alt: "Rails logo"),
'http://rubyonrails.org/' %>
#追加
<% end %>
上のコードを動かすにはいくつかのパーシャルを作る必要がある。
サイドバーで表示するユーザー情報のパーシャル
<%= link_to gravatar_for(current_user, size: 50), current_user %>
<h1><%= current_user.name %></h1>
<span><%= link_to "view my profile", current_user %></span>
<span><%= pluralize(current_user.microposts.count, "micropost") %></span>
↑ではユーザーが投稿したマイクロポストの総数が表示されるようになっている。
pluralizeメソッド
を使って “1 micropost” や “2 microposts” と表示するように調整している。
マイクロポスト投稿フォームのパーシャル
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<% end %>
上記のフォームを動かすには、2箇所の変更が必要となる。
一つ目はhomeアクションに@micropostを定義すること。
class StaticPagesController < ApplicationController
def home
@micropost = current_user.microposts.build if logged_in?
end
def help
end
def about
end
def contact
end
end
current_userメソッド
はユーザーがログインしているときしか使えないから、@micropost変数
もログインしているときのみ定義されるようになる。
もう一つの変更はエラーメッセージのパーシャルを再定義すること。
前回はエラーメッセージパーシャルが @user変数
を直接参照していたが今回は代わりに @micropost変数
を使う必要がある。
これらのケースをまとめると、フォーム変数fをf.objectとすることによって、関連付けられたオブジェクトにアクセスすることができる。
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(object.errors.count, "error") %>.
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
この修正により、ユーザー登録・パスワード再設定・ユーザー編集のそれぞれのビューも変更する必要がある。
<%= render 'shared/error_messages', object: f.object %>
<%= render 'shared/error_messages', object: f.object %>
<%= render 'shared/error_messages', object: f.object %>
これによりマイクロポスト投稿フォームが動くようになる。
HOMEページ
にまだマイクロポストを表示する部分が実装されていないから今の段階では投稿した内容をすぐに見ることができない。
ユーザー自身のポストを含むマイクロポストのフィードがないと不便となるのでfeedメソッド
をUserモデルで作る。
フィードの原型では、まずは現在ログインしているユーザーのマイクロポストをすべて取得する。
class User < ApplicationRecord
.
.
.
# 試作feedの定義
# 完全な実装は次章の「ユーザーをフォローする」を参照
def feed
Micropost.where("user_id = ?", id)
end
private
.
.
.
end
↑のコードは↓のコードと本質的に同等となるが、↑の方が応用が効きやすいため↑を採用する。
def feed
microposts
end
サンプルアプリケーションでフィードを使うために、現在のユーザーのページ分割されたフィードに @feed_itemsインスタンス変数
を追加し、次にフィード用のパーシャルを Homeページ
に追加する。
class StaticPagesController < ApplicationController
def home
if logged_in?
@micropost = current_user.microposts.build
#追加
@feed_items = current_user.feed.paginate(page: params[:page])
end
end
def help
end
def about
end
def contact
end
end
<% if @feed_items.any? %>
<ol class="microposts">
<%= render @feed_items %>
</ol>
<%= will_paginate @feed_items %>
<% end %>
後は、いつものようにフィードパーシャルを表示すればHomeページにフィードを追加できる。
<% if logged_in? %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<section class="micropost_form">
<%= render 'shared/micropost_form' %>
</section>
</aside>
<div class="col-md-8">
<h3>Micropost Feed</h3>
#追加
<%= render 'shared/feed' %>
</div>
</div>
<% else %>
.
.
.
<% end %>
これでマイクロポストの作成はうまくいくようになった。
ただマイクロポストの投稿が失敗すると、 Homeページは @feed_itemsインスタンス変数
を期待しているため、現状では壊れてしまう。
よって空の配列を渡しておく。
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
#追加
@feed_items = []
render 'static_pages/home'
end
end
def destroy
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
end
###マイクロポストを削除する
最後の機能として、マイクロポストリソースにポストを削除する機能を追加する。
これはユーザー削除と同様に、"delete"
リンクを使用する。
ユーザーの削除は管理者ユーザーのみが行えるように制限されていたのに対し、今回は自分が投稿したマイクロポストに対してのみ削除リンクが動作する。
最初のステップとして、マイクロポストのパーシャルに削除リンクを追加。
<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.
<% if current_user?(micropost.user) %>
#追加
<%= link_to "delete", micropost, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</span>
</li>
次に、Micropostsコントローラのdestroyアクション
を定義する。
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
上記ではrequest.referrer
というメソッドを使っている。
このメソッドはフレンドリーフォワーディングの request.url変数
と似ていて、一つ前のURLを返す。(今回の場合、Homeページになる)
ちなみに、元に戻すURLが見つからなかった場合でも、||演算子でroot_urlをデフォルトに設定している。
###マイクロポストの画像投稿
マイクロポストの基本はこれで実装できた。
これにプラスで画像投稿もできるようにする。
投稿した画像を扱ったり、その画像を Micropostモデル
と関連付けするために、今回はCarrierWave
という画像アップローダーを使う。
まずは carrierwave gem
を Gemfile
に追加し、mini_magick gem
と fog gems
も含めて追加しておく。
これらのgemは画像をリサイズしたり、本番環境で画像をアップロードするために使う。
source 'https://rubygems.org'
.
.
gem 'carrierwave', '1.2.2'
gem 'mini_magick', '4.7.0'
.
.
group :production do
gem 'fog', '1.42'
.
次に、いつものようにbundle install
を実行する。
$ bundle install
CarrierWave
を導入すると、Railsのジェネレーターで画像アップローダーが生成できるようになる。
$ rails generate uploader Picture
次に必要となる picture属性
を Micropostモデル
に追加するために、マイグレーションファイルを生成し、開発環境のデータベースに適用させる。
$ rails generate migration add_picture_to_microposts picture:string
$ rails db:migrate
CarrierWave
に画像と関連付けたモデルを伝えるためには、mount_uploader
というメソッドを使う。
このメソッドは、引数に属性名のシンボルと生成されたアップローダーのクラス名を取る。
class Micropost < ApplicationRecord
belongs_to :user
default_scope -> { order(created_at: :desc) }
#追加
mount_uploader :picture, PictureUploader
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 140 }
end
システムによっては、ここで一旦Railsサーバーを再起動させる必要がある。
マイクロポスト投稿フォームに画像アップローダーを追加するには file_fieldタグ
を含める必要があり、以下のようにする。
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<span class="picture">
#追加
<%= f.file_field :picture %>
</span>
<% end %>
最後に、Webから更新できる許可リストに picture属性
を追加する。
追加すると、micropost_paramsメソッド
は次の通り。
class MicropostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
.
.
.
private
def micropost_params
params.require(:micropost).permit(:content, :picture)
end
def correct_user
@micropost = current_user.microposts.find_by(id: params[:id])
redirect_to root_url if @micropost.nil?
end
end
一度画像がアップロードされれば、Micropostパーシャル
の image_tagヘルパー
でその画像を描画できるようになる。
また、画像の無い (テキストのみの) マイクロポストでは画像を表示させないようにするために、picture?
という論理値を返すメソッドを使う。
このメソッドは、画像用の属性名に応じて、CarrierWaveが自動的に生成してくれるメソッドとなる。
<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 %>
#追加
<%= image_tag micropost.picture.url if micropost.picture? %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</span>
</li>
###画像の検証
上記のままではアップロードされた画像に対する制限がないため、もしユーザーが巨大なファイルを上げたり、無効なファイルを上げると問題が発生してしまう。
この欠点を直すために、画像サイズやフォーマットに対するバリデーションを実装し、サーバー用とクライアント (ブラウザ) 用の両方に追加するようにする。
最初のバリデーションでは、有効な画像の種類を制限していくが、これは CarrierWave
のアップローダーの中に既にヒントがある。
生成されたアップローダーの中にコメントアウトされたコードがありますが、ここのコメントアウトを取り消すことで、画像のファイル名から有効な拡張子 (PNG/GIF/JPEGなど) を検証することができるようになる。
class PictureUploader < CarrierWave::Uploader::Base
storage :file
# アップロードファイルの保存先ディレクトリは上書き可能
# 下記はデフォルトの保存先
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# アップロード可能な拡張子のリスト
def extension_whitelist
%w(jpg jpeg gif png)
end
end
2つ目のバリデーションでは、画像のサイズを制御する。
これはMicropostモデル
に書き足してく。
先ほどのバリデーションとは異なり、ファイルサイズに対するバリデーションはRailsの既存のオプション (presenceやlengthなど) にはない。
したがって、今回は手動でpicture_sizeという独自のバリデーションを定義する。
class Micropost < ApplicationRecord
belongs_to :user
default_scope -> { order(created_at: :desc) }
mount_uploader :picture, PictureUploader
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 140 }
#追加
validate :picture_size
private
# アップロードされた画像のサイズをバリデーションする
def picture_size
if picture.size > 5.megabytes
errors.add(:picture, "should be less than 5MB")
end
end
end
このvalidateメソッドでは、引数にシンボル (:picture_size) を取り、そのシンボル名に対応したメソッドを呼びだす。
次に上で定義したバリデーションをビューに読み込むために、クライアント側に2つの処理を追加する。
まず file_fieldタグ
に acceptパラメータ
を付与し、大きすぎるファイルサイズに対して警告を出すために、ちょっとした**JavaScript(jQuery)**を書き加えることでバリデーションが動くようになる。
<%= form_for(@micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
<%= f.text_area :content, placeholder: "Compose new micropost..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<span class="picture">
#追加
<%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>
</span>
<% end %>
#追加
<script type="text/javascript">
$('#micropost_picture').bind('change', function() {
var size_in_megabytes = this.files[0].size/1024/1024;
if (size_in_megabytes > 5) {
alert('Maximum file size is 5MB. Please choose a smaller file.');
}
});
</script>
###画像のリサイズ
ファイルサイズに対するバリデーションはできたから、さいごに画像サイズ (縦横の長さ) に対する制限を追加する。
画像をリサイズするためには、画像を操作するプログラムが必要になる。
今回はImageMagick
というプログラムを使うので、これを開発環境にインストールする。
$ sudo yum install -y ImageMagick
次に、MiniMagick
というImageMagickとRubyを繋ぐgemを使って、画像をリサイズを試みる。
今回はresize_to_limit: [400, 400]
という方法を使用しこれは、縦横どちらかが400pxを超えていた場合、適切なサイズに縮小するオプションとなる。
class PictureUploader < CarrierWave::Uploader::Base
#追加
include CarrierWave::MiniMagick
process resize_to_limit: [400, 400]
storage :file
# アップロードファイルの保存先ディレクトリは上書き可能
# 下記はデフォルトの保存先
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# アップロード可能な拡張子のリスト
def extension_whitelist
%w(jpg jpeg gif png)
end
end
これで画像に対する制御もすみ、マイクロポスト機能を実装することができた。
##さいごに
今回はマイクロポスト機能の実装がメインとなりプラスアルファで画像投稿機能を実装できた。
残るは14章のフォロー機能だけとなる。
次↓
https://qiita.com/jonnyjonnyj1397/items/91c50bb5ac1d48bc29d3