Githubみたいな画像アップロードをInlineAttachment x ActiveStorageで実装する方法

GithubやQiitaのような画像アップロードをRailsのActiveStorageで実装してみました！

## サンプルリポジトリ

https://github.com/ihatov08/inline_attachment_rails

## ActiveStorageのセットアップ

```
rails active_storage:install
```

```
rails db:migrate
```

## InlineAttachmentのセットアップ

- 必要なファイルを[InlineAttachment](https://github.com/Rovak/InlineAttachment)からapp/assets/javascripts/以下にダウンロード
  - https://github.com/Rovak/InlineAttachment/blob/master/dist/inline-attachment.js
  - https://github.com/Rovak/InlineAttachment/blob/master/dist/jquery.inline-attachment.js

```
wget https://raw.githubusercontent.com/Rovak/InlineAttachment/master/dist/inline-attachment.js -P app/assets/javascripts/
```

```
wget https://raw.githubusercontent.com/Rovak/InlineAttachment/master/dist/jquery.inline-attachment.js -P app/assets/javascripts/
```

- 今回は`inline-attachment`を付与したtext_areaに対して、ドラッグアンドドロップの画像アップロードを適用するようにします。
- postリクエスト先は`/upload/image`です。後でcontrollerを作成します

```js:app/assets/javascripts/application.js
//= require inline-attachment
//= require jquery.inline-attachment

$(function(){
  $('.inline-attachment').inlineattachment({
    urlText: '<img src="{filename}">',
    uploadUrl: "/upload/image",
    uploadFieldName: "asset[file]",
    allowedTypes: ['image/jpeg', 'image/png', 'image/jpg', 'image/gif'],
    extraHeaders: {"X-CSRF-Token": $("meta[name=csrf-token]").attr("content")}
  });
});
```

## jquery-railsのセットアップ

InlineAttachmentでjqueryを使用するので、jquery-railsをセットアップ

```ruby:Gemfile
gem 'jquery-rails'
```

```js:app/assets/javascripts/application.js
//= require jquery
```

## 画像アップロード用のcontroller作成

- 今回は画像をモデルに紐付けるのではなく、ActiveStorageのダイレクトアップロードを使います。

```
rails g controller upload image
```

```ruby:app/controllers/upload_controller.rb
class UploadController < ApplicationController
  def image
    file = params[:asset][:file]
    blob = ActiveStorage::Blob.create_after_upload!(
      io: file,
      filename: file.original_filename,
      content_type: file.content_type
    )

    render json: { filename: url_for(blob) }
  end
end
```

## 画像アップロード確認用scaffold

```
rails g scaffold body:text
```

```
rails db:migrate
```

## text_areaにclass付与

- jsで定義したhtmlのクラスを付与します
- 同時に見やすいようにsizeで幅を広げておきます

```erb:app/views/posts/_form.html.erb
<%= form.text_area :body, class: "inline-attachment", size: "100x50" %>
```

## 画像を見れるようにerbを修正

```erb:app/views/posts/show.html.erb
<%== @post.body %>
```

## 画像投稿テスト

http://localhost:3000/posts/new

ドラッグアンドドロップしてみると、imgタグが挿入されていますね。

ログにもinsertが走っています。

```rb
Started POST "/upload/image" for 127.0.0.1 at 2018-11-22 02:09:09 +0900
Processing by UploadController#image as */*
  Parameters: {"asset"=>{"file"=>#<ActionDispatch::Http::UploadedFile:0x00007f0818760418 @tempfile=#<Tempfile:/tmp/RackMultipart20181122-19296-dyym8x.jpg>, @original_filename="image-1542820149354.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"asset[file]\"; filename=\"image-1542820149354.jpg\"\r\nContent-Type: image/jpeg\r\n">}}
  Disk Storage (1.6ms) Uploaded file to key: kw5WzruEFiiEDDwkqtNXZHnK (checksum: rkmRclvUbaP9VARI0QxhAw==)
   (0.1ms)  begin transaction
  ↳ app/controllers/upload_controller.rb:4
  ActiveStorage::Blob Create (0.3ms)  INSERT INTO "active_storage_blobs" ("key", "filename", "content_type", "metadata", "byte_size", "checksum", "created_at") VALUES (?, ?, ?, ?, ?, ?, ?)  [["key", "kw5WzruEFiiEDDwkqtNXZHnK"], ["filename", "image-1542820149354.jpg"], ["content_type", "image/jpeg"], ["metadata", "{\"identified\":true}"], ["byte_size", 33760], ["checksum", "rkmRclvUbaP9VARI0QxhAw=="], ["created_at", "2018-11-21 17:09:09.416249"]]
  ↳ app/controllers/upload_controller.rb:4
   (6.3ms)  commit transaction
  ↳ app/controllers/upload_controller.rb:4
Completed 200 OK in 51ms (Views: 0.2ms | ActiveRecord: 7.4ms)
```


![image.png](https://qiita-image-store.s3.amazonaws.com/0/93394/44749052-9188-af12-2708-0432d7e5fda8.png)


記事を作成してみると、、、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/93394/16272102-e212-d73f-fe7c-c66545cec7e5.png)

成功しました！

## 参考
- https://qiita.com/megane42/items/afc64a15adccf571445f
- https://medium.com/weareevermore/manual-uploads-using-activestorage-47808dab1b65