Dragon Arrow written by Tatsuya Nakaji, all rights reserved animated-dragon-image-0164

wysiwyg-rails imageUploadToS3 / wysiwygエディタからS3にアップロード

イメージ
Dec 10, 2018

wysiwyg-rails imageUploadToS3


これは、Rails4の時代まではこちらの方 のやり方で良かったみたいですけど、amazonの署名の方法に変更が加わったからなのか、今では正常に動作しないため、何十時間(50~100h)も使ってたどり着いた筆者の苦悩の物語です。


前提: すでにwysiwyg-railsを使ってエディターの実装ができている(できないのはファイルのサーバーへのアップロードのみ)

$(function() {
  $('#wysiwyg').froalaEditor({
  language: 'ja',
  heightMin: 500,
  heightMax: 1000,
  })
});


結論から言って、自作モジュールを作らずに, froala-editor-sdkを使って解決することができました。


はじめにクライアント側の設定

Gemfile

gem 'wysiwyg-rails', '~> 2.6.0' (2.6.6をインストール)
gem "froala-editor-sdk" (1.2.0をインストール)


articles_controller

class ArticlesController < ApplicationController
before_action :find_article, only: [:edit, :update, :show, :destroy]
before_action :require_login, except: [:index, :show]
before_action :hash_init, only: [:index, :new, :create, :edit]


def index
@articles = Article.all
end

def new
@article = Article.new
end

def create
@article = Article.new(article_params)
if @article.save
flash[:notice] = "保存されました"
redirect_to article_path(@article)
else
flash[:alert] = "エラーが発生しました"
render :new
end
end

def edit
end

def update
  if @article.update_attributes(article_params)
    flash[:notice] = "更新されました"
    redirect_to article_path(@article)
  else
    flash[:alert] = "エラーが発生しました"
    render :edit
  end
end

def show
end

def destroy
  if @article.destroy
    flash[:notice] = "削除されました"
    redirect_to articles_path
  else
    flash[:alert] = "エラーが発生しました"
  end
end

private

def find_article
@article = Article.find(params[:id])
end

def hash_init
  options = {
    bucket: 'mybucket',
    region: 'ap-northeast-1', # japan[Tokyo]
    keyStart: 'uploads/', # uploads/filename.png
    acl: 'public-read',
    accessKey: ENV["aws_access_key_id"],
    secretKey: ENV["aws_secret_access_key"],
  }
    @aws_data = FroalaEditorSDK::S3.data_hash(options)
end


end

自作ライブラリでハッシュするのではなく、FroalaEditorSDKを使って、ハッシュ化を行いました。

そして公式ドキュメントを見ればわかるのですが、なんと公式ドキュメントが間違っているという事態が発覚。

options : {

  bucket: 'bucket-name',

...

}

となっていますが、 options : ではなく options = ですので間違いのないようにイコールで書いてください.


_form.html.erb

<%= simple_form_for (@article) do |f| %>
<% if @article.errors.any? %>
<div id="error_explanation">
<h2>
<%= "#{pluralize(@article.errors.count, "error")} このエラーにより保存できませんでした" %>
</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li>
<%= msg %>
</li>
<% end %>
</ul>
</div>
<% end %>

<div class="form-group">
<%= f.input :title, class: "form-control" %>
</div>

<div class="form-group">
<%= f.input :image, as: :file, class: "form-control" %>
</div>

<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, id: "wysiwyg" %>
</div>

<div class="form-group">
<%= f.button :submit, "投稿", :class => 'btn btn-primary' %>
</div>
<% end %>

<script>
$(function() {
$('#wysiwyg').froalaEditor({
language: 'ja',
heightMin: 500,
heightMax: 1000,
imageUploadToS3: <%= @aws_data.to_json.html_safe %>,
})
});
</script>


new.html.erb

<h2>New Article</h2>
<%= render "articles/form", collection: @aws_data %>


edit.html.erb

<h2>Edit Article</h2>
<%= render "articles/form", collection: @aws_data %>


これでクライアント側は完璧です


次にサーバー側の設定

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>http://localhost:3000</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>


これでサーバ側も完璧です


以上で無事に投稿できました!!本当にしんどかった...