Sunday, March 9, 2014

Update Blog with Tags

Step 1: Set up a Model and Join Table

$ rails g model Tag name

$ rails g model Post_Tag post_id:integer tag_id:integer

$ rake db:migrate

Step 2: Add many-to-many relationship into Models

In app/models/post.rb,

class Post < ActiveRecord::Base
  attr_accessible :body, :title, :author_id

  belongs_to :author

  has_many :comments

  has_many :favourites

  has_many :post_tags
  has_many :tags, through: :post_tags

  validates_presence_of :body, :title
end

In app/models/post_tag.rb,

class PostTag < ActiveRecord::Base
  belongs_to :post

  belongs_to :tag
end

In app/models/tag.rb,

class Tag < ActiveRecord::Base
  attr_accessible :name

  has_many :post_tags
  has_many :posts, through: :post_tags
  
  validates_presence_of :name
end

Step 3: Adding new methods into Posts Controller

In app/controllers/posts_controller.rb,

class PostsController < ApplicationController
  before_filter :authenticate, :except => [ :index, :show ]

  # ... all the action go in here

  def delete_tags
    tag = Tag.find(params[:tag_id])
    post = Post.find(params[:post_id])
    if tag.destroy
      redirect_to post_path(post) #redirect_to action: :index
    end
  end

  # the authentication action
end

Step 4: Adding Create Tag methods into Tags Controller

In app/controllers/tags_controller.rb,

class TagsController < ApplicationController
  def create
   @post = Post.find(params[:post_id])
    @tag = @post.tags.create(params[:tag])
    redirect_to @post
  end
end

Step 5: Connecting URLs to Code by Editing Routes Config

In config/routes.rb,

QuickBlog::Application.routes.draw do
  resources :authors

  resources :comments

  get '/posts/add_favourite', to: 'posts#add_favourite'
  get '/posts/delete_favourite', to: 'posts#delete_favourite'
  get '/posts/delete_tags', to: 'posts#delete_tags'
  resources :posts do
    resources :comments, :only => [:create, :destroy]
  end
end

Step 6: Edit the Views in Posts

In app/views/posts/show.html.erb,

  <p id="notice"><%= notice %></p>

  <%= render :partial => @post %>

  by <%= @post.author.name %>
  <br/>

  <%= link_to 'Edit', edit_post_path(@post) %> |
  <%= link_to 'Back', posts_path %>

  <p><%= link_to 'Add Favourite', "/posts/add_favourite?post_id=#{@post.id}" %> (<%= @post.favourites.size %>) | <%= link_to 'Delete Favourite', "/posts/delete_favourite?post_id=#{@post.id}" %></p>

  <h2>Tags</h2>
  <div id="tags">
    <%#= @post.tags.map(&:name).join(", ") %>
    <% @post.tags.each do |tag| %>
      <%= tag.name %> - <%= tag.created_at.strftime("%B %e, %Y %l:%M %p") %> [<%= link_to "delete", "/posts/delete_tags?tag_id=#{tag.id}&post_id=#{@post.id}" %>]<br/> <!--"delete #{tag.name}" -->
    <% end %>

  </div>

<%= form_for [@post, Tag.new] do |f| %>
    <p>
        <%= f.label :name, "New tag" %><br/>
        <%= f.text_field :name %>
    </p>
    <p><%= f.submit "Add tag" %></p>
<% end %>

  <!-- Comments -->

Return to Internship Note (LoanStreet)
Previous Episode: Update Blog with Favourites (Part 2)
Next Episode: Authentication with Devise

0 comments:

Post a Comment