user2647092
user2647092

Reputation: 397

Routes not working correctly

EDIT: Thanks for the replies, I tried everything listed below but still now luck. If I type localhosts/posts/new it takes me to the form, however the link does not work when I click from the navigation bar. I've updated the code and included my rake routes results.

I am new to ruby and working through a tutorial, however one of my links is not working and not sure what is happening.

My navigation link to create a new post is not taking me to the correct page, when I click the link to the "posts_path" the page does not change.

I can create a new posts by typing in the /posts/new in the address bar, but when I click the "New Post" link on the nav bar the page does not update (although the url displays /posts). Any idea how to fix this?

config/routes.rb

Rails.application.routes.draw do
get 'sessions/new'
root 'static_pages#home'
get  '/search', to: 'static_pages#search'
get  '/login', to: 'sessions#new'
get  '/posts', to: 'posts#new', as: 'new_post'
post  '/login', to: 'sessions#create'
delete  '/logout', to: 'sessions#destroy'
get  '/signup', to: 'users#new'
get 'users/new'
get 'static_pages/home'
get 'posts/new'
get 'sessions/new'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :posts, only: [:new, :create, :destroy]
end

app/views/layouts/_header.html.erb

<header class="navbar navbar-fixed-top navbar-inverse">
<div class="container">
  <% link_to "sample app", root_path, id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home", root_path %></li>
        <li><%= link_to "Search", search_path %></li>
          <% if logged_in? %>
            <li><%= link_to "Users", users_path %></li>
            <li><%= link_to "Posts", posts_new_path %></li>
            <li class="dropdown">
             <a href='#' class="dropdown-toggle" data-toggle="dropdown">Account <b class="caret"></b></a>
             <ul class="dropdown-menu">
              <li><%= link_to "Profile", current_user %></li>
              <li><%= link_to "Settings", edit_user_path(current_user) %></li>
              <li class="divider"></li>
              <li><%= link_to "Logout", logout_path, method: "delete" %></li>
             </ul>
           </li>
           <% else %>
             <li><%= link_to "Log in", login_path %></li>
           <% end %>
          </ul>
       </nav>
  </div>

posts_controller.rb

class PostsController < ApplicationController
    before_action :logged_in_user, only: [:create, :destroy]
    before_action :correct_user, only: :destroy

    def create
            @post = current_user.posts.build(post_params)
            if @post.save
                    flash[:success] = "Post created!"
                    redirect_to root_url
            else
                    @feed_items = []
                    render 'static_pages/home'
            end
    end

    def destroy
            @post.destroy
            flash[:success] = "Post Deleted"
            redirect_to request.referrer || root_url
    end
    def new
       @post = current_user.posts.build if logged_in?
    end

    private

    def post_params
            params.require(:post).permit(:description, :picture)
    end

    def correct_user
            @post = current_user.posts.find_by(id:params[:id])
            redirect_to root_url if @post.nil?
    end
end

rake routes:

password_resets_new     GET     /password_resets/new(.:format)          password_resets#new
password_resets_edit    GET     /password_resets/edit(.:format)         password_resets#edit
sessions_new            GET     /sessions/new(.:format)                 sessions#new
root                    GET     /                                       static_pages#home
search                  GET     /search(.:format)                       static_pages#search
login                   GET     /login(.:format)                        sessions#new
new_post                GET     /posts(.:format)                        posts#new
                        POST    /login(.:format)                        sessions#create
logout                  DELETE  /logout(.:format)                       sessions#destroy
signup                  GET     /signup(.:format)                       users#new
users_new               GET     /users/new(.:format)                    users#new
static_pages_home       GET     /static_pages/home(.:format)            static_pages#home
static_pages_about      GET     /static_pages/about(.:format)           static_pages#about
static_pages_search     GET     /static_pages/search(.:format)          static_pages#search
posts_new               GET     /posts/new(.:format)                    posts#new
                        GET     /password_resets/new(.:format)          password_resets#new
                        GET     /password_resets/edit(.:format)         password_resets#edit
                        GET     /sessions/new(.:format)                 sessions#new
help                    GET     /help(.:format)                         static_pages#help
about                   GET     /about(.:format)                        static_pages#about
contact                 GET     /contact(.:format)                      static_pages#contact
users                   GET     /users(.:format)                        users#index
                        POST    /users(.:format)                        users#create
new_user                GET     /users/new(.:format)                    users#new
edit_user               GET     /users/:id/edit(.:format)               users#edit
user                    GET     /users/:id(.:format)                    users#show
                        PATCH   /users/:id(.:format)                    users#update
                        PUT     /users/:id(.:format)                    users#update
                        DELETE  /users/:id(.:format)                    users#destroy
edit_account_activation GET     /account_activations/:id/edit(.:format) account_activations#edit
password_resets         POST    /password_resets(.:format)              password_resets#create
new_password_reset      GET     /password_resets/new(.:format)          password_resets#new
edit_password_reset     GET     /password_resets/:id/edit(.:format)     password_resets#edit
password_reset          PATCH   /password_resets/:id(.:format)          password_resets#update
                        PUT     /password_resets/:id(.:format)          password_resets#update
posts                   POST    /posts(.:format)                        posts#create
                        GET     /posts/new(.:format)                    posts#new
post                    DELETE  /posts/:id(.:format)                    posts#destroy

Upvotes: 6

Views: 13290

Answers (11)

Falknn
Falknn

Reputation: 246

Remove get 'sessions/new' & get '/posts', to: 'posts#new', as: 'new_post'

Restart server

and try link_to "Posts", new_post_path, method: :post

Should work

Upvotes: 3

Shannon Scott Schupbach
Shannon Scott Schupbach

Reputation: 1278

The bottom line is that you're trying to do things in a non-Rails manner. Rails favors convention over configuration, meaning if you don't do things the Rails way, you're going to have a bad time.

This means you should clean up your routes until you have no unnecessary duplication. Right now you have 3 different routes that go to posts#new each with a different path prefix.

I'd remove:

  • get '/posts', to: 'posts#new', as: 'new_post'
  • get 'posts/new'

since resources :posts, only: [:new, :create, :destroy] already creates that route. Then your new_post_path helper should create the correct URL and your routes will have no ambiguity.

Upvotes: 1

Milind
Milind

Reputation: 5112

i went through your code...and this is what i recommend to add/edit changes..and sure it should work :).

  1. for routes.rb,its looks good BUT there is a duplicate url entry.So either remove get 'posts/new' or resources :posts, only: [:new, :create, :destroy] as they both will create a duplicate entry for posts#new.You can verify this by outputting your routes in seperate txt file by rake routes >> path.txt
  2. in app/views/layouts/_header.html.erb,its good too and dont need any change.
  3. in posts_controller.rb,there is a condition added for only logged in user,Kindly check if you are logged in else remove that condition and check again.
  4. Finally,debug using F12 in chrome/firefox and see what log do you get in web browser console before and after click to check is there some javascript error or not.

Upvotes: 2

Sachin srinivasan
Sachin srinivasan

Reputation: 828

The problem is there is conflict occurring in your routes. You have defined routes twice for new

get /posts', to: 'posts#new', as: 'new_post'

and

resources :posts, only: [:new, :create, :destroy]

now there are 2 paths for posts#new. I suggest u remove first one. Change your html to

<li><%= link_to 'New Post', posts_path %></li>

and it should work fine.

Upvotes: 2

Sumit Dey
Sumit Dey

Reputation: 81

As per your rake routes output the following should work

<%= link_to "New Post", posts_new_path %>

Please let us know whether there any error comming in the console log on clicking the new post link.

Upvotes: 1

Satishakumar Awati
Satishakumar Awati

Reputation: 3798

Rails scans the routes from top to bottom i.e. routes.rb. Whenever it finds the matching routes corresponding controller#action gets executed and remaining all will be skipped(later routes after match found).

In this case routes are conflicting, So do bellow changeseverything will work fine. config/routes.rb

Rails.application.routes.draw do
get 'sessions/new'
root 'static_pages#home'
get  '/search', to: 'static_pages#search'
get  '/login', to: 'sessions#new'
#get  '/posts', to: 'posts#new', as: 'new_post' #not required as resources :posts will do the job in last line
post  '/login', to: 'sessions#create'
delete  '/logout', to: 'sessions#destroy'
get  '/signup', to: 'users#new'
get 'users/new'
get 'static_pages/home'
get 'posts/new', to: 'posts#new', as: 'posts_new_path'  #Made changes here according to helper used in view 'posts_new_path'
get 'sessions/new'
resources :users
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resources :posts, only: [:new, :create, :destroy]
end 

Upvotes: 2

Prabha
Prabha

Reputation: 21

This may be helps to redirect,
in routes.rb,

resources :posts  

It gives the paths to all default controller methods like index, new, create, edit, update, show, destroy. Then check with rake routes. Get the corresponding path like,

new_post GET      /posts/new(.:format)                    posts#new  

if it correct means give the url like,

<%= link_to 'New Post', new_post_path %>
It redirects to method new in controller and render corresponding html.erb page. This url formed by the routes.rb.

OR

push the redirection url manually.In html page,

<%= button_tag "New", :onclick => "getNew()" %>   
function getNew(){
        var form = document.forms[0];
        // get the id and value with any variable // 
        form.method = "post";       
        // pass the value to parameters //
        form.var name = column name; (description r picture) 
        form.action = "posts/new";
        form.submit();
    }  

in routes.rb,

match '/posts/new' => 'posts#new', via: [:get, :post]  

It makes the manual redirection url. It calls the new in controller method.
Let me know your feedback! Thanks

Upvotes: 1

Stephen W
Stephen W

Reputation: 244

I would suggest that you remove get 'posts/new' & get '/posts', to: 'posts#new', as: 'new_post' as these are duplicate routes.

You already have the correct route created in the route resources :posts, only: [:new, :create, :destroy]. By including new, Rails is doing this portion for you. See here: http://guides.rubyonrails.org/v4.2/routing.html#crud-verbs-and-actions

Then you should be able to use the link that everyone else has posted. <%= link_to "New Post", new_post_path %> based on the guide here: http://guides.rubyonrails.org/v4.2/routing.html#path-and-url-helpers

Upvotes: 2

RamPrasad Reddy
RamPrasad Reddy

Reputation: 125

<%= link_to "Posts", posts_path %> corresponds to index action not to the new action.

Remove the only condition for your posts controller in routes.rb which will create all the basic routes needed rather than specific routes.

resources :posts

So, new_post_path returns /posts/new

Finally add a link link <%= link_to 'New Post', new_post_path %>

Upvotes: 1

abax
abax

Reputation: 787

Try new_post_path

Also, rake routes in terminal will list all the routes and associated helpers for you to double check against.

Finally, adding 'as' to: get '/posts', to: 'posts#new', as: 'new_post' in your routes file will allow you to define your own path name (in this case new_post_path, but you can set it as anything you'd like).

Upvotes: 1

abhi110892
abhi110892

Reputation: 300

code for link to new post

<%= link_to "New Post", new_post_path %>

Upvotes: 1

Related Questions