0

In my feed I have this:

<span class="title"><strong><%= link_to feed_item.title, @micropost %></strong></span><br>

I cannot figure out how to make it link to the individual pages for posts.

Right now it links to: http://localhost:3000/microposts and I get an error: No route matches [GET] "/microposts"

if I manually type the URL: http://localhost:3000/microposts/25 I can see the indivual page for the post.

This works fin linking to a user profile, but I can't get the link working to a micropost's page. <%= link_to feed_item.user.name, feed_item.user %>

I'm new to rails and I'm trying to figure this out. Any help would be appreciated.

microposts_controller.rb

class MicropostsController < ApplicationController
  before_filter :signed_in_user, only: [:create, :destroy]
  before_filter :correct_user,   only: :destroy

  def index
  end

  def show
    @micropost = Micropost.find(params[:id])
  end

  def create
    @micropost = current_user.microposts.build(params[:micropost])
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to root_url
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end

  def destroy
    @micropost.destroy
    redirect_to root_url
  end

  private

  def correct_user
    @micropost = current_user.microposts.find_by_id(params[:id])
    redirect_to root_url if @micropost.nil?
  end
end

config/routes.rb

SampleApp::Application.routes.draw do
  resources :users do
    member do
      get :following, :followers
    end
  end
  resources :sessions, only: [:new, :create, :destroy]
  resources :microposts, only: [:create, :destroy, :show]
  resources :relationships, only: [:create, :destroy]

  root to: 'static_pages#home'

  match '/signup',  to: 'users#new'
  match '/signin',  to: 'sessions#new'
  match '/signout', to: 'sessions#destroy', via: :delete

  match '/help',    to: 'static_pages#help'
  match '/about',   to: 'static_pages#about'
  match '/contact', to: 'static_pages#contact'
end

_feed_item.html.erb

<li id="<%= feed_item.id %>">
  <%= link_to gravatar_for(feed_item.user), feed_item.user %>
  <span class="title"><strong><%= link_to feed_item.title, micropost_path(@micropost) %></strong></span><br>
    <span class="user">
      <p><small>Created by: <%= link_to feed_item.user.name, feed_item.user %><br>
        <%= feed_item.loc1T %><br>
         <%= feed_item.startTime.strftime('%A, %B %d, %Y') %></small></p>
    </span>
    <span class="content"><%= feed_item.content %></span>
    <span class="timestamp">
      Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
    </span>
  <% if current_user?(feed_item.user) %>
    <%= link_to "delete", feed_item, method: :delete,
                                     data: { confirm: "Are you sure?" },
                                     title: feed_item.content %>
  <% end %>
</li>

feed.html.erb

<% if @feed_items.any? %>
  <ol class="microposts">
    <%= render partial: 'shared/feed_item', collection: @feed_items %>
  </ol>
  <%= will_paginate @feed_items %>
<% end %>`

static_pages_controller

class StaticPagesController < ApplicationController
  def home
    if signed_in?
      @micropost  = current_user.microposts.build
      @feed_items = current_user.feed.paginate(page: params[:page])
    end
  end

  def help
  end

  def about
  end

  def contact
  end
end
Teoulas
  • 2,943
  • 22
  • 27
Livi17
  • 1,620
  • 3
  • 25
  • 43

1 Answers1

3

Long answer

Rails generates a number of handy named routes for you when you add routes to your routes.rb file. Usually when in doubt for routes I take a look at my rake routes task which shows you a list of all available routes. Try running rake routes > routes.txt and open up the corresponding routes.txt file.

The resulting file will list out a series of requests for you, in your case you should see something similar to this for your microposts controller:

          POST      /microposts(.:format)                microposts#create
micropost GET       /microposts/:id(.:format)            microposts#show
          DELETE    /microposts/:id(.:format)            microposts#destroy

Rake routes produces the following information for each of your routes (where applicable):

  1. The route name (if any)
  2. The HTTP verb used (if the route doesn’t respond to all verbs)
  3. The URL pattern to match
  4. The routing parameters for the route

With that information in mind be can simply look at the urls provided in the routes.txt file for the url we're trying to get to (/microposts/25). You'll see that the listed /microposts/:id(.:format) url pattern handles that perfectly. Lo and behold it also maps to the microposts#show action that you want so now to get the named route just look at the first column to appear and you'll see the "microposts" keyword. Simply add _path` to this and you'll have your named route usable in views to generate link urls. Since this particular route requires an id parameter (as detailed in the url pattern) you have to pass the named route helper and id argument as well.

Also in your routes.rb file when you add resources :something it generates routes for each of the default seven RESTful routes (new, create, edit, update, delete, index, show). In your case you're explicitly telling rails to generate default routes for the actions create, destroy and show so you can erase the line at the bottom match "/microposts/:id" => "microposts#show" because that's already being handled.


Short answer

Change this:

<%= link_to feed_item.title, @micropost %>

To this:

<%= link_to feed_item.title, micropost_path(feed_item) %>

See Ruby on Rails Guides: Rails routing from the Outside In for all you need to know about routes.

Noz
  • 6,216
  • 3
  • 47
  • 82
  • Thank you for the informative post. When I tried your short answer solution, I get the following Action Controller: Exception Caught Routing Error: `No route matches {:action=>"show", :controller=>"microposts", :id=># – Livi17 Oct 16 '12 at 01:37
  • What does the instance variable @feed_items represent? Is that just an array of microposts that you're looping through in your feed listing? If not what is the relationship between microposts and feed items. If I was to take a guess you probably want to replace `@microposts` with `feed_item` in the short answer I provided. – Noz Oct 16 '12 at 18:23
  • @cycle Hunter yes, the the feed is an array of microposts. I posted my static_pages_controller... not sure if that makes a difference. – Livi17 Oct 16 '12 at 18:30
  • @Cycle Hunter... this worked! <%= link_to feed_item.title, micropost_path(feed_item) %> Thanks a lot. I was pulling my hair out! – Livi17 Oct 16 '12 at 18:41
  • Happy to help, just try and be a little more consistent with semantics & variable naming in the future to avoid confusing yourself, I would even rename @feed_items to @microposts for the sake of clarity. If you had a model called `Bananas`, you would represent a variable of many Bananas as simply "@bananas" as opposed to "@delicious_yellow_fruits". – Noz Oct 16 '12 at 18:49
  • Good advice. I didn't pick those names. They were part of the Ruby On Rails tutorial by Michael Hartl. In the future I will keep that in mind, though. – Livi17 Oct 17 '12 at 13:14