Question
How do I implement tags in Rails without plugins?
I have a Rails application, similar to a blog, and I would like add some tags to the posts.
I see that there are some plugins / gems for tagging:
https://www.ruby-toolbox.com/categories/rails_tagging
However they all seem cumbersome for my use case (e.g. they include many Rails migrations).
How can I implement tagging in Rails from scratch?
Answer
You can add tags to a Rails model (e.g. Post
) using PostgreSQL arrays.
First you need to add a new column for tags to your model:
class AddTagsToPosts < ActiveRecord::Migration[7.0]
def change
add_column :posts, :tags, :string, array: true, null: false, default: []
add_index :posts, :tags, using: :gin
end
end
This adds an array column for tags
to the posts
table in the database. It also adds an index in order to filter by tag.
Then in your Post
model:
class Post < ApplicationRecord
before_validation :normalize_tags
def tag_list= list
self.tags = list.split(',').map(&:strip)
end
def tag_list
self.tags.join(', ')
end
private
def normalize_tags
self.tags.map!(&:parameterize)
end
end
We do two different things here:
-
Tag normalization (e.g. convert “My awesome tag!” to “my-awesome-tag”)
-
Define an additional attribute setter and getter in order to deal with tags like comma-separated strings (this can be useful later in the view in order to use a simple text field)
Then in the controller you have:
def post_params
params.require(:post).permit(:title, :body, :tag_list)
end
And in the form view:
<%= f.text_field :tag_list %>
Finally you can access tags normally as an array:
@post.tags.each { |t| puts t }