I'm trying to implement act_as_taggable into my Rails 4 app (upon the microposts model), but the program isn't saving the tags, which therefore aren't viewable. The tables for tags and taggings have been raked and exist in the database, but none of the code I'm implemented seems to save a tag or create a tag when the form is submitted. I followed the steps in this tutorial near exactly, but something doesn't seem to work.
I'm not sure if it's a rails 4 centric problem and/or is connected to the lack of 'attr_accessible' code used in rails. Since the code example doesn't specify adding anything to the microposts table, I can only assume the connection is made elsewhere, but where and how I should fix that I don't know (in microposts_helper.rb perhaps?).
Thanks in advance. Any help is greatly appreciated.
Relevant Code Snippets
Gemfile
...
gem 'acts-as-taggable-on', '~> 2.4.1'
...
microposts.rb
class Micropost < ActiveRecord::Base
belongs_to :user
acts_as_taggable
acts_as_taggable_on :tags
...
end
microposts_controller.rb
before_action :signed_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def index
if params[:tag]
@microposts = Micropost.tagged_with(params[:tag])
else
@microposts = Micropost.all
end
end
def create
@micropost = current_user.microposts.build(micropost_params)
if @micropost.save
flash[:success] = "Micropost created!"
redirect_to current_user
else
@feed_items = []
render 'users/show'
end
end
def destroy
@micropost.destroy
redirect_to user_url
end
def tagged
if params[:tag].present?
@microposts = Micropost.tagged_with(params[:tag])
else
@microposts = Micropost.postall
end
end
private
def micropost_params
params.require(:micropost).permit(:content)
end
def correct_user
@micropost = current_user.microposts.find_by(id: params[:id])
redirect_to user_url if @micropost.nil?
end
end
microposts_helper.rb
module MicropostsHelper
include ActsAsTaggableOn::TagsHelper
end
_microposts_form.html.rb
<%= form_for(@micropost) do |f| %>
...
<div class="field">
...
<%= f.label :tags %>
<%= f.text_field :tag_list %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
_micropost.erb.html
<li>
<span class="content"><%= micropost.content %></span>
<span class="tags">
<%= micropost.tag_list %>
</span>
...
</li>
schema.rb
...
create_table "microposts", force: true do |t|
t.string "content"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "microposts", ["user_id", "created_at"], name: "index_microposts_on_user_id_and_created_at"
...
create_table "taggings", force: true do |t|
t.integer "tag_id"
t.integer "taggable_id"
t.string "taggable_type"
t.integer "tagger_id"
t.string "tagger_type"
t.string "context", limit: 128
t.datetime "created_at"
end
add_index "taggings", ["tag_id"], name: "index_taggings_on_tag_id"
add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context"
create_table "tags", force: true do |t|
t.string "name"
end
...
routes.rb
Dev::Application.routes.draw do
...
resources :microposts, only: [:create, :destroy]
...
match 'tagged', to: 'microposts#tagged', :as => 'tagged', via: 'get'
end
If I understand the question correctly, all you should need to do is, essentially, tell the recommended protection model for params(strong_parameters) about the acts-as-taggable gem. Your already Halfway there with this:
private
def micropost_params
params.require(:micropost).permit(:content)
end
[...]
end
Just add:
private
def micropost_params
params.require(:micropost).permit(:content, :tag_list => [])
end
[...]
end
Also, you may want to add one thing to your routes.rb file.. Replace the line:
resources :microposts, only: [:create, :destroy]
with:
resources :microposts, only: [:create, :destroy, :tag]
Let me know if these suggestions do the trick. Good luck!