Using ActionText in Rails 6

ActionText brings rich text editing into Rails. ActionText includes the Trix, "A rich text editor for everyday writing", from the team over at Basecamp. Trix is an improved WYSIWYG style editor that gives us more control over what happens when the user presses a key.


What is ActionText?


ActionText is the latest addition to the Rails framework. It allows us to create rich text content, store it in a table, then attach it to any of our models. It is super simple to set up and produces great results. 

ActionText uses the Trix editor to help create rich content. Trix is a WYSIWYG style editor that redesigns how a WYSIWYG editor works on the web. Most WYSIWYG editors are based on undocumented Microsoft APIs that were reverse-engineered to work in other browsers, causing inconsistencies across the browsers. Rather than taking this approach, Trix uses an contenteditable element as an IO device. When a user presses a key, Trix converts the input into an edit operation on the editors internal model then re-renders the contenteditable element to show the changes. This removes the need to use inconsistent APIs and also grants developers much more control over the output.

Why would you want to use ActionText?


Rich text can be used in a range of scenarios to great effect, I'm currently typing this post using ActionText. You could also use it to create a rich chat system, take detailed notes, or allow code-blocks and quotes within comments. You could even create a basic CMS to generate static pages for a website using ActionText, as we can attach this to an AR model we can also store other attributes like page-title, SEO meta tags etc on the record.

Just hook it up and your canvas is ready!

ActionText is super simple to set up and provides enough features to be a great solution for a lot of features. You can use the ActionText::Attachment to create customized experiences. We created a couple of custom attachments including the link to our careers page like this one below (wink wink)

Looking for a new challenge? Join Our Team



How do we get this working?


First we need to install Trix and include the JS and CSS

$ bin/rails action_text:install

// application.js
require("trix")
require("@rails/actiontext")

// actiontext.scss
@import "trix/dist/trix";

// application.scss
@import "./actiontext.scss";

Now we can attach it to a model, render a rich_text_area in our form, then render the content and we're done

# app/models/blog_post.rb
class BlogPost < ApplicationRecord
  has_rich_text :content
end

<%# app/views/blog_post/_form.html.erb %>
<%= form_with model: blog_post do |form| %>
  <div class="field">
    <%= form.label :content %>
    <%= form.rich_text_area :content %>
  </div>
<% end %>

<%# app/views/blog_post/_form.html.erb %>
<%= @blog_post.content %>

Uploading images is handled by ActiveStorage so there's nothing for us to do there except configure our storage provider. 

One thing to remember for both ActiveStorage and ActionText is to preload the associations as they are stored in their own tables, ActionText provides two named scopes to preload the associations.

BlogPost.with_rich_text_content.find(params[:id])
BlogPost.with_rich_text_content_and_embeds.find(params[:id])

Are there any issues with ActiveStorage?


ActionText isn't perfect. Out of the box it doesn't support tables but the developers at timelapse have come up with a clever way around that by embedding tables as Trix attachments and editing the tables in their own UI

Where did you go data?

There are a couple issues that I find frustrating. Because we're using a contenteditable instead of a native input (textarea or input) to render the content we lose some of the standard behavior. 

If you accidentally close the window while you are editing the content your data is lost. With a textarea you can often reopen the closed window and you'll find all of the information you've typed out still there saved in memory. Trix, however, uses the browser in an "unexpected" way so the optimizations browsers have implemented to save this data are not triggered.

Another quirk is that the ⌘Del (on mac) shortcut to delete a whole line doesn't work reliably. Often it will delete more or less than the current line. I believe this is also due to Trix using a contenteditable element instead of a normal HTML input that the OS knows how to interact with.

Would I recommend ActionText?


Absolutely... depending on your use case. If you're building something that would benefit from rich text, you want it fast, and you want it to work then yes, ActionText is great. If you want super fine grain control it might not be the best solution for you; something like SlateJS might do a better job. The cost to value ratio is obvious though; you get a lot for your time. Right off the bat you have a really great editor that is more than capable of creating some really great UX. Now that Trix has been introduced to Rails a lot more people will be using it which means more improvements will be coming and it's likely here to stay. You can fairly safely invest time into implementing ActionText in your application without fear of the maintainers dropping support. I'm certain we will see a lot of improvements and innovative ways to customize it in the coming years.

Congratulation it's a contenteditable


Like 1 like
Joe Woodward
I'm Joe Woodward, a Ruby on Rails fanatic working with OOZOU in Bangkok, Thailand. I love Web Development, Software Design, Hardware Hacking.
Share:

Join the conversation

This will be shown public
All comments are moderated

Get our stories delivered

From us to your inbox weekly.