Tagging
Learn how to implement a many-to-many tagging system in your Rails blog using join models. Organize content with tags like “ruby” or “rails” for easy navigation.
Understanding Tag Relationships
Tags allow categorizing articles for better organization. The relationship between articles and tags is many-to-many:
- An article can have multiple tags
- A tag can belong to multiple articles
Database Modeling
We implement this using three models:
Article
(existing)Tag
(new)Tagging
(join model)
Generating the Models
Create the new models with these commands:
rails generate model Tag name:string
rails generate model Tagging tag:references article:references
rake db:migrate
Setting Up Model Relationships
Article Model
app/models/article.rb
:
has_many :taggings
has_many :tags, through: :taggings
Tag Model
app/models/tag.rb
:
has_many :taggings
has_many :articles, through: :taggings
def to_s
name
end
Tagging Model
app/models/tagging.rb
:
belongs_to :tag
belongs_to :article
Tagging Interface Implementation
Adding Tag Input to Article Form
Add to app/views/articles/_form.html.erb
:
<p>
<%= f.label :tag_list, "Tags (separated by commas)" %><br />
<%= f.text_field :tag_list %>
</p>
Article Model Methods
Add to app/models/article.rb
:
def tag_list
tags.join(", ")
end
def tag_list=(tags_string)
tag_names = tags_string.split(",").collect{|s| s.strip.downcase}.uniq
new_or_found_tags = tag_names.collect { |name| Tag.find_or_create_by(name: name) }
self.tags = new_or_found_tags
end
Strong Parameters
Update article_params
in your controller:
def article_params
params.require(:article).permit(:title, :body, :tag_list)
end
Displaying Tags
Show Tags on Article Page
Add to app/views/articles/show.html.erb
:
<p>
Tags:
<% @article.tags.each do |tag| %>
<%= link_to tag.name, tag_path(tag) %>
<% end %>
</p>
Tag Management
Generate Tags Controller
rails generate controller tags
Update Routes
config/routes.rb
:
resources :tags
Tags Controller
app/controllers/tags_controller.rb
:
def show
@tag = Tag.find(params[:id])
end
def index
@tags = Tag.all
end
def destroy
@tag = Tag.find(params[:id])
@tag.destroy
flash.notice = "Tag '#{@tag.name}' deleted."
redirect_to tags_path
end
Tag Views
app/views/tags/show.html.erb
:
<h1>Articles Tagged with <%= @tag.name %></h1>
<ul>
<% @tag.articles.each do |article| %>
<li><%= link_to article.title, article_path(article) %></li>
<% end %>
</ul>
app/views/tags/index.html.erb
:
<h1>All Tags</h1>
<ul>
<% @tags.each do |tag| %>
<li>
<%= link_to tag.name, tag_path(tag) %>
<%= link_to "delete", tag_path(tag), method: :delete,
data: {confirm: "Really delete the tag?"} %>
</li>
<% end %>
</ul>
Testing in Console
# Create article with tags
article = Article.create(
title: "Sample Tagged Article",
body: "Content goes here",
tag_list: "ruby, rails, programming"
)
# View article's tags
article.tags
# View articles with a specific tag
tag = Tag.first
tag.articles
Final Steps
Commit your changes:
git add .
git commit -m "Tagging feature completed"
git push
Now your blog has a fully functional tagging system!
Adding Comments
This guide walks you through creating a Comment model, setting up one-to-many associations with articles, building a comment form, handling form submissions, displaying comments, and adding timestamps using Rails best practices.
A Few Gems
Learn how to enhance your Rails app by integrating RubyGems like Paperclip for file uploads. Set up gems, migrations, and image attachments easily.