jiksun
jiksun

Reputation: 3

How do I create 'remove tag' links with Acts_As_Taggable_On in Rails?

I'm creating a simple project tagging application using the Act_As_Taggable_On gem.

Adding projects, and adding tags (in my case 'types' / 'type_list') to each project works great. Where I'm stuck is how to remove individual tags using Act_As_Taggable_On. What I would like is to be able to click the 'x' text link next to each tag (see link) to remove the tag from that projects type_list.

I've searched the documentation and found a method along the lines of:

project.type_list.remove("your tag")

But what I need help with is how to call the remove method on the specific tag, especially since the whole thing is being iterated with .each do

My controller and model code is pretty minimal and standard - based on Act_As_Taggable_On docs. Here is my view code for generating the layout above:

<h1><%= @title %></h1>
<div class="column-left">
  <% @projects.each do |project| %>
    <div class="p_wrapper">

      <table>
        <tr>
          <td><div class="project p_name"><%= project.name %></div></td>
          <td><div class="p_link"><%= link_to 'Edit', edit_project_path(project) %></div></td>
          <td><div class="p_link"><%= link_to 'Nuke', project, :confirm => 'Are you sure?', :method => :delete %></div></td>
        </tr>
      </table>

      <table>
        <tr>
          <td>
              <% project.type_list.each do |tag|%>
                <div class="p_tag">
                <%= tag %> 
                <%= link_to "x", # %> <!-- THIS IS THE PART I'M STUCK ON -->
              </div> 
              <% end %>
            </td>
        </tr>
      </table>

      <table>
        <tr>
            <td>
              <%= form_for(project) do |f| %>
              <%= f.text_field :inject_tags %>  
              <%= f.submit "Add Tag" %>
              <% end %>
            </td>
        </tr>
      </table>

    </div>

  <% end %>

  <br />

  <%= link_to 'Add new project', new_project_path %>
</div>

Can anyone point me in the right direction? Am I implementing this correctly to be able to actually remove tags as described?

Thanks guys!

Upvotes: 0

Views: 854

Answers (2)

jiksun
jiksun

Reputation: 3

Based on @Vapire's suggested code - finally worked out a working solution. Just some minor edits to the view, route, and controller. Let me know if you see anything dodgy in here - still trying to get a good grasp of Ruby/Rails so all suggestions/refactoring ideas welcome.

The updated test site is at project-list.heroku.com.

Updated projects controller to find current project, remove :tag passed from index view through route:

def remove_tag
  @project = Project.find(params[:id])
  @project.type_list.remove(params[:tag])
  @project.save
  redirect_to projects_path, :flash => { :success => "Updated - tag nuked."}
end

Updated route:

resources :projects
match 'projects/:id/remove_tag/:tag' => 'projects#remove_tag'

Updated the link_to 'x' code to pass :tag params through the updated route above:

<% project.type_list.each do |tag|%>
  <div class="p_tag">
    <%= tag %> 
    <%= link_to 'x', {:action => "remove_tag", :id => project.id, :tag => tag, 
    :controller => "projects"} %>
  </div> 
<% end %>

This is obviously new ground for me so would appreciate if you have a different / better way of handling this issue please let me know! Also, thanks for your help @Vapire!

Upvotes: 0

Vapire
Vapire

Reputation: 4578

I would simply add a new method to your projects controller, like so:

def remove_tag
  Project.find(params[:id]).type_list.remove(params[:tag])
end

And in your routes file

resources :projects do
  member do
    put 'remove_tag', :as => :remove_tag
  end
end

And in your view

<%= link_to 'x', remove_tag_project_path(project), :tag => tag, :method => :put %>

Of course you should add some sanitation, but it should work this way...

Upvotes: 1

Related Questions