Skip to content

Instantly share code, notes, and snippets.

@FluffyCode
Created February 19, 2015 00:13
Show Gist options
  • Save FluffyCode/90c57e07c3a200ea5b56 to your computer and use it in GitHub Desktop.
Save FluffyCode/90c57e07c3a200ea5b56 to your computer and use it in GitHub Desktop.
acts-as-taggable-on in Rails 4
This information originally found at:
http://www.reddit.com/r/rails/comments/2chtgw/tagging_in_rails_4/
Saving it here, in case it helps/is lost in the future.
Installation
Gemfile
gem 'acts-as-taggable-on'
terminal
bundle install
terminal
rake acts_as_taggable_on_engine:install:migrations
rake db:migrate
This creates some tables and doesn't need to know anything specific about your models.
The models and concerns for working with these tables (Tag, Tagging, etc) live inside the gem.
Model integration
app/models/post.rb
class Post
acts_as_taggable
end
Now you can do, eg:
post = Post.create
post.tag_list = "programming, ruby, rails"
post.tag_list
# => ['programming', 'ruby', 'rails']
#tag_list= takes a string and splits it up, using the resulting substrings to find_or_create Tags, and associate them with the taggable thing (eg, Post), through Taggings. You don't need to know this.
The important thing is that, with #tag_list= we can manage tags via a comma-separated-list in a text field in a form.
Controller integration
app/controllers/posts_controller.rb
class PostsController < ApplicationController
def create
@post = Post.create(post_params)
redirect_to @post
end
def post_params
params.require(:post).permit(:title, :body, :tag_list)
end
end
This is assuming you're trying to tag an existing Post model with title and body fields, web-accessible through an existing PostsController, with index, show, new, etc. methods.
Substitute your own, the important machinery here is whitelisting tag_list from the params.
Form integration
app/views/posts/_form.html.erb
<%= form_for post do |f| %>
<%= f.text_field :title %>
<%= f.text_area :body %>
<%= f.text_field :tag_list %>
<%= f.submit %>
<% end %>
Let me know if you don't know how to use this partial to do new/edit, and I'll elaborate.
Now you can create tags for stuff. How about displaying them? Couple options, I'll go through the most explicit (a TagsController with index and show actions), but they can be rolled up into other controllers/actions.
Controller
config/routes.rb
Rails.application.routes.draw do
resources :posts
resources :tags, only: [:index, :show]
end
app/controllers/tags_controller.rb
class TagsController < ApplicationController
def index
@tags = ActsAsTaggableOn::Tag.all
end
def show
@tag = ActsAsTaggableOn::Tag.find(params[:id])
@posts = Post.tagged_with(@tag.name)
end
end
It's unfortunate we have to do this slightly awkward workaround with Post.tagged_with(@tag.name) in tags#show. The ActsAsTaggableOn::Tag model does not have a built-in relationship with its taggable types (this is a necessary consequence of some polymorphism which we're not using here). We could add one for Post, but this way is easier to demonstrate.
Tags Views
app/views/acts_as_taggable_on/tags/_tag.html.erb
<%= link_to tag.name, tag_path(tag) %>
app/views/tags/index.html.erb
<h1>Tags</h1>
<%= render @tags %>
app/views/tags/show.html.erb
<h1><%= @tag.name %></h1>
<div><%= render @posts %></div>
Note the partial path is acts_as_taggable_on/tags/tag. This is so we can just say render @tags and let rails do its implicit magic. There are other ways to organize everything, but this is the simplest.
View integration
app/views/posts/_post.html.erb
<h2><%= link_to post.title, post_path(post) %></h2>
<div><%= render post.tags %></div>
app/views/posts/index.html.erb
<h1>Posts</h1>
<%= render @posts %>
app/views/posts/show.html.erb
<h1><%= @post.title %></h1>
<div><%= @post.body %></div>
<div><%= render @post.tags %></div>
And that should be it. It'll look shitty, but I hope you can figure out how to elaborate on this once you have it working. If anything here is assuming familiarity with something you don't have, ask and I will gladly elaborate.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment