19
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rails6でドラッグ&ドロップ可能なマークダウンエディタを作成する(Active StorageとSimpleMDEとInline Attachmentを使用)

Posted at

概要

Rails6でQiitaの投稿画面のように、画像をドラッグ&ドロップ可能なMarkdownエディタを作成した際のメモです。

img.gif

参考コードはこちら

ちなみにRailsをGWに学んで、このエディタ機能を実装したblogを作成しました。
(Heroku,GCSで構築)
地元の静岡県東部のスポット等を紹介していますので興味があればどうぞ。
駿河部

環境

Mac OS 10.15.4
Ruby 2.6.3p62
Rails 6.0.2.2

使用する機能について

主に3つのOSS及び機能を使用して実装をしています。

  • SimpleMDE
  • Inline Attachment
  • Active Storage

SimpleMDE

ブラウザ上のtextareaタグをMarkdownエディタを変えてくれる素晴らしいOSS。
自動保存機能など様々な機能も搭載されています。

リンク

Inline Attachment

ブラウザ上からドラッグ&ドロップでのAjaxでのファイル送信を簡単に実装してくれる。
SimpleMDEと組み合わせて、ドラッグ&ドロップされた画像を非同期で送信してアップロード結果をエディタに反映してくれます。

リンク

Active Storage

Railsに組み込まれているファイルアップロードの機能。
こいつを利用するとお手軽にファイルアップロード機能が実装可能で、AWS,Azure,GCPといったクラウドストレージへのアップロードにも対応している優れもの。

手順

PJの作成と各種インストール


# railsのプロジェクト作成
rails new markdown_drag_and_drop

# active storageのインストール
rails active_storage:install
rails db:migrate

# 必要なjsモジュールのインストール
yarn add simplemde
yarn add inline-attachment

turbolinksの無効化

Railsにはデフォルトで高速化のために、通常のWEBサイトをSPAのような部分的なDOM変更に無理やり置き変えるturbolinksが入っています。
しかしながら、jsでゴリゴリと実装をする上でよく悪さをするので今回は無効化しています。

app/javascript/packs/application.js

// 無効化
// require("turbolinks").start()
app/views/layouts/application.html.erb

<!-- 'data-turbolinks-track': 'reload'を削除 -->
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_pack_tag 'application' %>

モデル、コントローラ、ビューの作成

scaffoldで雛形を作成します。
contentがMarkdownを文字列として保存するフィールドとしています。

rails g scaffold article content:text

フォーム画面にMarkdownエディタにするtextareaを配置します。

app/views/articles/_from.html.erb
<!-- 画面で使用するjs(後で記載) -->
<%= javascript_pack_tag 'article' %>

<%= form_with(model: article, local: true) do |form| %>
 <!-- 略 -->

<div class="field">
    <%= form.label :content %>
    <%= form.text_area :content, { id: "editor"} %>
</div>

<div class="actions">
    <%= form.submit %>
</div>
<% end %>

画面で読み込むjsを作成する。

  • textareaのエディタ化
  • エディタ内にドラッグ&ドロップされた際にajax通信する設定

を行います。
ajaxで通信する処理はこの後作成します。

app/javascript/packs/article.js

import "inline-attachment/src/inline-attachment";
import "inline-attachment/src/codemirror-4.inline-attachment";
import 'simplemde/dist/simplemde.min.css'
import SimpleMDE from "simplemde";
import Rails from '@rails/ujs'

window.onload = function () {
  // textareaをMarkdownエディタにする
  const simplemde = new SimpleMDE({
    element: document.getElementById("editor"),
  });
  // エディタに画像がドラッグ&ドロップされた際の処理
  inlineAttachment.editors.codemirror4.attach(simplemde.codemirror, {
    uploadUrl: "/articles/attach", // POSTする宛先Url
    uploadFieldName: "image", // ファイルのフィールド名(paramsで取り出す時のkey)
    allowedTypes: ['image/jpeg', 'image/png', 'image/jpg', 'image/gif'],
    extraHeaders: { "X-CSRF-Token": Rails.csrfToken() }, // CSRF対策
  });
};

ファイル送信用の処理の作成

Active Storageでファイル送信を行うためのモデルを作成します。

rails g model attachment
app/models/attachment.rb
class Attachment < ApplicationRecord
    has_one_attached :image
end

scaffoldで作成したコントローラにajax通信用の処理を追加する。
画像の保存及びURLをJSONで返します。
filenameがinlineAttachmentがデフォルトで受け取るパラメータなのでそれに合わせます。

app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  ...
  def attach
    attachment = Attachment.create! image: params[:image]
    render json: { filename: url_for(attachment.image) }
  end
  ...
end

ルーティングに追加します。

routes.rb
  post 'articles/attach', to: 'articles#attach'

動作確認

実行して、エディタにうまくドラッグ&ドロップして、画像リンク用のMarkdownが出力されれば成功です。

rails db:migrate
rails s

画像のリサイズ

アップロード画像をそのまま返すのではなく、
リサイズしたいものを使用したい場合には、variantで圧縮したものを返すことも可能です。
ActiveStorageは圧縮もやってくれるので楽ですね。

app/models/attachment.rb
class Attachment < ApplicationRecord
  has_one_attached :image

  def image_compressed
    if image.attached?
      image.variant(resize_to_fit: [700, 600]).processed
    end
  end
end

まとめ及び所感

Rails6で画像をドラッグ&ドロップ可能なMarkdownエディタを作成する方法を紹介しました。
最近Railsを触りだしたのですが、色々と暗黙のルールを覚えないといけない事はありますが、様々な処理が簡単に実装できるため楽ですね。

参考

19
15
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?