チワワかわいいブログ

RUNTEQでrails勉強する日々の記録

2020/12/20 railsチュートリアル13章

micropostを削除する
before_action :correct_user,   only: :destroy
  
def destroy
    @micropost.destroy #@micropostにはbefore actionで正しいか先に確認した投稿が入っている
    flash[:success] = "Micropost deleted"
    redirect_to request.referrer || root_url  #投稿一覧があるページどこからでも投稿できる。
end

def correct_user
      @micropost = current_user.microposts.find_by(id: params[:id])  #自分が関連している投稿の中に、params[:id]の投稿は含まれているか、含まれていればその投稿が代入、なければnil
      redirect_to root_url if @micropost.nil? #nilだと自分の投稿ではないのでリダイレクト
end

redirect_to request.referrer || root_url
投稿一覧があるページどこからでも投稿できる。
request.referrerでどこのページからリクエストを送ったか、が取得できるのでそこにridrect、なければ(直接リクエストを飛ばしたり)ホーム。

画像投稿

Railsに組み込まれているActive Storageという機能を用いる
$ rails active_storage:install
添付ファイルの保存に用いるデータモデルを作成するためのデータベースマイグレーションが1つ生成される
has_one_attached :image
モデルにオプションを追加。画像を1投稿に対していくつ紐付けるか。引数入るものは何を紐づけるのかを明示するだけで、他のデータが保存できないわけではない。

<span class="image">
    <%= f.file_field :image %>
</span>

フォームにfile_fieldを追加。
micropostのcreateアクションに保存するためのコードを追加。

@micropost.image.attach(params[:micropost][:image])

active_storgaeは「.image.attach」というメソッドが使えるようになる。
直前のコードで、@micropostにparamsを代入しており、このコードでmicropostに画像を追加できるので、その後に保存。
現時点でstrong parameterで弾かれちゃうので、変更。
micropostのパーシャルに表示用のコードを追加。

<%= image_tag micropost.image if micropost.image.attached? %>
画像のvalidation

active_strageではgemを使ってみる

gem 'active_storage_validations', '0.8.2'

このgemをインストーツすることで、content_type、sizeというハッシュを渡してvalidationが指定できるようになる。
これを使ってvalidationを書く。

画像アップロードする前、添付した時点でわかれば親切。
javascript使って実装

<script type="text/javascript">
  $("#micropost_image").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.");
      $("#micropost_image").val("");
    }
  });
</script>

さっき追加したフォームに、画像のフォーマットの指定を追加

<%= f.file_field :image, accept: "image/jpeg,image/gif,image/png" %>
画像のリサイズ

ImageMagickを使う。
インストールすると、Active Storageが提供するvariantメソッドで変換済み画像を作成できるようなり、resize_to_limitオプションを用いて、画像の幅や高さが制限をかけたりすることができるようになる

  # 表示用のリサイズ済み画像を返す
  def display_image
    image.variant(resize_to_limit: [500, 500])
  end