DEV Community

Lucas Barret
Lucas Barret

Posted on

Action Text

Action Text is a ruby gem that is part of Rails. It enables you to write and display rich text in your app.

But how does it work ?

Install Action Text

First thing first let's set up our issue. You want to create a blog.
Obviously in this blog you have articles.

You create an article table and in this table you have a content column.

Eventually you decide that you would like to add rich text to these article content.

You use Action Text, so let's install it :
bin/rails action_text:install

This generates a migration so you just need to run them.

Eventually in your model article.rb you just have to add has_rich_text :content and Voilà !

How this table works

This table is a polymorphic table where you store the name of the record and the id of the record.

A row from this table look like this :

ActiveRecord::Base.connection.execute("select * from action_text_rich_texts")

{
  "id" => 3,
  "body" => "the body of your content",
  "created_at" => "2025-10-26 10:39:22.112279",
  "name" => "content",
  "record_id" => 2,
  "record_type" => "Article",
  "updated_at" => "2025-10-26 17:17:09.672582"
}
Enter fullscreen mode Exit fullscreen mode

And when you update your article content like this :

Article.find(2).update(content: 'new content')

It will not update the content of the article but the body of the related action_text_rich_text.

Article.find(2).attributes

{
  "id" => 2,
  "content" => nil, # content is nil
  "created_at" => 2025-10-26 10:39:22.106595000 UTC +00:00,
  "updated_at" => 2025-10-26 17:17:09.674060000 UTC +00:00
}

ActiveRecord::Base.connection.execute("select * from action_text_rich_texts")

{
  "id" => 3,
  "body" => "new content",
  "created_at" => "2025-10-26 10:39:22.112279",
  "name" => "content",
  "record_id" => 2,
  "record_type" => "Article",
  "updated_at" => "2025-10-26 17:17:09.672582"
}
Enter fullscreen mode Exit fullscreen mode

How is this working ?

This is done in fact through a simple trick : redefining the getter of the Article class.

And this is done thought the has_rich_text dsl that you use earlier.

class_eval <<-CODE, __FILE__, __LINE__ + 1
  def #{name}=(body)
    self.#{name}.body = body
  end
CODE
Enter fullscreen mode Exit fullscreen mode

And why it works ? Because create use new that use the getter to affect variable with the setter of the class.

This also means that the bulk edit method, like insert_all and update_all does not work.

Conclusion

That's it you know how rich text work and how the magic happens

Top comments (0)