I'm currently reading the "Getting Started with Rails"-tutorial. I'm confused about the Action Text-section.
I've added the "has_rich_text :description"-function to my Product-model. After the migration everything works as expected.
But within the "schema.rb" there isn't a field "description".
create_table "products", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
Where is the value of "description" persisted?
What does the "has_rich_text" do? How does it all come together in the end?
Actually I would expect a change to the product database-table to be necessary.
ActionText takes an approach where all the texts for all your models are stored in a single table.
This is the migration generated when you run the rails g action_text:install
task.
class CreateActionTextTables < ActiveRecord::Migration[6.0]
def change
# Use Active Record's configured type for primary and foreign keys
primary_key_type, foreign_key_type = primary_and_foreign_key_types
create_table :action_text_rich_texts, id: primary_key_type do |t|
t.string :name, null: false
t.text :body, size: :long
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
t.timestamps
t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
end
end
private
def primary_and_foreign_key_types
config = Rails.configuration.generators
setting = config.options[config.orm][:primary_key_type]
primary_key_type = setting || :primary_key
foreign_key_type = setting || :bigint
[ primary_key_type, foreign_key_type ]
end
end
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
creates a polymorphic assocation to potentially any model in your application.
This design lets you add the functionality to any model without any changes to it's tables and that ActionText just has to deal with it's own tables instead of having a lot of knowledge of the class using it.
It's an opinionated design that leans heavility towards convention over configuration and convinience.
ActiveStorage does the same thing with it's active_storage_attachments
table and it's other tables for blobs and variants just refer to this table.
Actually I would expect a change to the product database-table to be necessary.
That would be one way to implement this kind of functionality but not the only way. The downside would be that it would require you to add those columns to every model using ActionText and ActionText would have to deal with the complexity of reading/writing to the model's table and with varying column names. If you add the fact that models can have several different ActionText "attributes" that compounds the complexity.
Another alternative would be to use one additional table per model. Which would let you have real foreign keys and smaller tables but with a heavy price in terms of configuration and complexity.