【rails】テキストエディターの実装(summernote)

#実装すること

・gem summernoteを使用して、投稿フォームをテキストエディターにする。
・テキストエディターでリンクや画像の投稿も簡単。

公式： https://summernote.org/
Github: https://github.com/summernote/summernote-rails
参考記事
①https://bagelee.com/programming/rails-wysiwyg-gem/

#完成形

・ 見た事があるテキストエディターが表示され、投稿詳細にも反映されています。
・ 他にも画像の添付、文字の太さの変更など機能様々。

![Hnet-image.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/8b50fb8e-d848-22b6-c1a4-803742f99c34.gif)


#前提

下記の機能実装済み。

・ devise機能(今回は、memberモデル)
・ 投稿機能(今回は、questionモデル)

```ruby:shema.rb
ActiveRecord::Schema.define(version: 2021_05_05_122222) do

  create_table "members", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.datetime "remember_created_at"
    t.string "name", default: "", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_members_on_email", unique: true"index_members_on_reset_password_token", unique: true
  end

  create_table "questions", force: :cascade do |t|
    t.integer "member_id", null: false
    t.string "title", default: "", null: false
    t.text "content", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["member_id"], name: "index_questions_on_member_id"
  end
end
```

#手順
1. gem"summernote"のインストール
2. assetsのcss/scss + jsファイルへの追記
3. summernote-init.coffeeの作成
4. viewへの記載①
5. viewへの記載②

#実装
###1. gem"summernote"のインストール

gemをインストールします。
ただ、githubを見る限り、summernote＋他のGemも同時にインストールします。
もし、既にインストールしているものがあれば、それを除いたものをインストールしましょう。

simple_formに関しては、
viewの書き方で使うか使わないかなので、**「viewへの記載」**をインストールするか判断してください。

```ruby:Gemfile
gem 'jquery-rails'
gem 'bootstrap', '~> 4.5'
gem 'simple_form'
gem 'summernote-rails', '~> 0.8.9'
```
```terminal:terminal
$ bundle install
```

###2. assetsのcss/scss + jsファイルへの追記

それぞれによって異なりますが、
application.css/scssファイル と jsファイルに下記を追加します。
＠importは、外部のcssファイルを読み込む際に使う記述です。

下記のscssファイルにおいては、
"summernote-bs4.css"というcssファイルを読み込むようにしています。

```css:assets/stylesheets/application.scss
 *= require social-share-button
 *= require_tree .
 *= require_self
 */      
@import "bootstrap";
@import "summernote-bs4";
```
application.jsも同様に読み込ませます。

```javascript:assets/javascripts/application.js
//= require jquery3
//= require popper
//= require bootstrap-sprockets
//= require rails-ujs
//= require summernote/summernote-bs4.min
//= require summernote-init
//= require activestorage
//= require turbolinks
//= require_tree .
//= require social-share-button
```

###3. summernote-init.coffeeの作成

先ほど下記を記載したかと思います。

```
//= require summernote-init
```
"summernote-init"のファイルは現状ない為、これから作成します。
これによってviewにテキストエディターを表示したり、カスタマイズしたりできます。


```coffee:assets/javascripts/summernote-init.coffee
$(document).on 'turbolinks:load', ->
  $('[data-provider="summernote"]').each ->
    $(this).summernote
      placeholder:"質問したい内容を記入しよう。一番見て欲しい箇所は色をつけるなどで強調してみよう！"
      height: 300
```

###4. viewへの記載 ①

先ほどsummernote-init.coffeeを機能させるには、下記をviewに記載する必要があります。

```coffee:assets/javascripts/summernote-init.coffee
[data-provider="summernote"]
```
なので、text_areaの中に記述します。、

```erb:questions/new.html.erb(抜粋)
<div class="form-group">
  <p class="font-weight-bold"><%= f.label :質問内容 %></p>
  <p><%= f.text_area :content, class:"form-control w-100", 'data-provider': :summernote %></p>
</div>
```
これによってcoffeeファイル(js)がその箇所と連動し、表示されます。

新規投稿画面にテキストエディターが表示されたかと思います。

【こちらは全文です。】

```erb:questions/new.html.erb
<%= form_with model: @question, local: true do |f| %>
  <%= render "layouts/error_messages", resource: @question %>
  <div class="form-group">
    <p class="font-weight-bold"><%= f.label :質問タイトル %></p>
    <%= f.text_field :title, placeholder: "タイトルを記入しましょう。(5〜50文字以内)", class:"form-control w-100" %>
  </div>
  <div class="form-group">
    <p class="font-weight-bold"><%= f.label :タグ %>(0個からいくつでも選択可能です。)</p>
    <p><%= f.collection_check_boxes :tag_ids, Tag.all, :id, :name, class:"form-control", prompt:"この中からタグを1つ選んでください。", mutiple: true %></p>
  </div>
  <div class="form-group">
    <p class="font-weight-bold"><%= f.label :質問内容 %></p>
    <p><%= f.text_area :content, class:"form-control w-100", 'data-provider': :summernote %></p>
  </div>
  <div class="form-action">
    <%= f.submit "質問する", class:"btn btn-success w-100" %>
  </div>
<% end %>
```

###5. viewへの記載 ②

最後にテキストエディターで投稿した文字の表示設定をします。

今のままでは、画像のようにタグが表示されているかと思います.
![スクリーンショット 2021-05-14 1.38.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1029483/a06638fa-c48f-40e6-d33a-e63f8ff33681.png)

これを正しく表示させるための記述を投稿詳細のviewに手を加えます。

解決策: https://qiita.com/iwamot/items/74c2bd9ebd3ac6458837

記事に書いてるエスケープ処理を使います。

```erb:questions/new.html.erb
<div class="questions-content offset-md-2">
  <h4><%== question.content %></h4>
</div>
```
通常：　　<%= %>
今回：　　<%== %>

と　＝　を2つつけます。
これによってview側での表示がテキストエディターでの文字設定が反映されます。

これで基本的にsummernoteは実装できたかと思います！！

#補足：原因不明のエラーに関して

無事実装でき、最初は表示されていたのですが、
突然表示されなかったり、エラーが出て動かなくなる。などがありました。

もしかしたらこれを参考にした方も同じ事が起きるかも？？しれません、、、、。
これに関して正直、なぜ起きたのか原因はわからずでした、、。

解決策としては、**summernote.js** をassetsファイルに格納したところ動きました。
参考までに。

以上です。