Search code examples
ruby-on-railsrubyrich-text-editorquill

How to capture content typed in a rich text editor and save it in a Rails model? - Quill rich editor


I'm new to this and I'm trying to create a rich text editor for my blog. I am using Quill as a rich text editor for my Ruby on Rails application. I have set it up, but I am now running into a problem of saving the content typed into the editor.

Here is my form:

<%= form_for @post do |f| %>
  <% if @post.errors.any? %>
    <h2><%= pluralize(@post.errors.count, "error")%> prevented this post from saving:</h2>
    <ul>
      <% @post.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
      <% end %>
    </ul>
  <% end %>

<%= f.label :title %><br>
<%= f.text_field :title %>

<%= f.label :content, "Write your article here" %><br><br />

<div class="editor">
  <div id="toolbar"></div>
  <div id="editor"></div>
</div>

<%= f.hidden_field :content, id: "form" %>

<%= f.submit "Publish" %>
<% end %>

<script src="https://cdn.quilljs.com/1.2.2/quill.js"></script>
<script>    
  var toolbarOptions = [
    ['bold', 'italic', 'underline', 'strike'],
    ['blockquote'],
    [{'header': [1, 2, 3, 4, 5, 6, false]}],
    [{'align': []}],
    [{'list': 'ordered'}, {'list': 'bullet'}],
    [{'color': [] }, { 'background': [] }],
    ['link', 'image', 'video'],
  ]

  var quill = new Quill('#editor', {
    modules: {
      toolbar: toolbarOptions
    },

    theme: 'snow'
  });
</script>

Here is my Posts controller:

class PostsController < ApplicationController
  before_action :find_post, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]
  before_action :load_user,  only: [:show]
  before_action :create,  only: [:unapprove]
  load_and_authorize_resource

  def load_user
    if @post.user != nil
      @user = @post.user
    end
  end

  def index
    @posts = Post.approved.all.order("created_at desc").paginate(page: params[:page], per_page: 15)
  end

  def new
    if user_signed_in?
      @post = current_user.posts.build
    else
      @post = Post.new
    end
  end

  def create
    if user_signed_in?
      @post = current_user.posts.build(post_params)
    else
      @post = Post.new(post_params)
    end

    if @post.save && @post.approved && @post.after_approved
      redirect_to @post, notice: "Congrats! Your post was successfully published on The Teen Magazine!"
    elsif @post.save
      redirect_to @post, notice: "Changes were successfully saved!"
    else
      render 'new', notice: "Oh no! Your post was not able to be saved!"
    end
  end

  def show
    redirect_to root_path unless (@post.approved || (current_user && (@post.user_id == current_user.id || current_user.admin?)))
    set_meta_tags title: @post.title,
                  description: @post.meta_description,
                  keywords: @post.keywords
  end

  def unapprove
    @post = Post.unscoped.update(params[:approve], :approved => false)
    render :action => :success if @post.save
  end

  def edit
  end

  def update
    if @post.update post_params
      redirect_to @post, notice: "Changes were successfully saved!"
    else
      render 'edit'
    end
  end

  def destroy
    @post.destroy
    redirect_to posts_path
  end

  private

  def post_params
    params.require(:post).permit(:title, :content, :image, :category, :category_id, :meta_title, :meta_description, :keywords, :user_id, :admin_id, :waiting_for_approval, :approved, :after_approved, :created_at, :slug)
  end

  def find_post
    @post = Post.friendly.find(params[:id])
  end
end

I need to save the content from Quill to 'content' in Posts.

Any help is much appreciated. Thank you.


Solution

  • This is because you "editor" is not bind to the "content" field.

    You need to either copy data from editor to content field on form submit. Call another JS function on submit button click, in that js function copy data from editor to content field and then submit the form using javascript.

    Another solution is, try to attach editor to text_area content field.

    <%= f.text_field :content %>
    

    and

    var quill = new Quill('#post_content', {
        modules: {
          toolbar: toolbarOptions
        },
    
        theme: 'snow'
      });
    

    You can append toolbar using using javascript.