Rika
Rika

Reputation: 171

Why is link not working? undefined local variable path or method ROR

I cannot get my link to work: Users can post job listings. Other users can view the job listing and click on apply. Now a form should appear for the user to fill out some information. However I cannot get the path and route file right. This is the link in show.html.erb that's now working

<li><%= link_to "Apply Now", listing_apply_path(id: listings.id) %></li>

The form is under views/listings/apply.html.erb

listings/show.html.erb

<div class="show_listing">

    <div class="col-md-6">
    <div class="col-md-6">
        <h3><%= @listing.title %></h3>
        <h3><%= @listing.location %></h3>
        <p><%= @listing.description %></p><br>
        <div class="center">
        <li><%= link_to "Apply Now", listing_apply_path(id: listings.id) %></li>
    </div>
    </div>
</div>
</div>

<div class="show_link_position">
<% if current_user == @listing.user %>
<%= link_to 'Edit', edit_listing_path, class: "btn btn-link" %> |
<% end %>
<%= link_to 'Back', current_user, class: "btn btn-link" %>
</div>

listings_controller.rb

    def apply
        @listing = Listing.find(params[:id])
      end

and routes

Rails.application.routes.draw do

  resources :categories

  get 'notifications/index'

  get 'notifications/create'

    resources :users
    resources :sessions, only: [:new, :create, :destroy]
    resources :listings



  root 'static_pages#home'


      match '/signup',  to: 'users#new',            via: 'get'
      match '/signin',   to: 'sessions#new',          via: 'get'
      match '/signout', to: 'sessions#destroy',     via:'delete'
      match '/help',      to: 'static_pages#help',    via: 'get'
      match '/contact',   to: 'static_pages#contact',  via: 'get'
      match '/about',     to: 'static_pages#about',   via: 'get' 
      match '/new',     to: 'listings#new',   via: 'get' 
      match '/users/:name/:id', to: 'listings#show', via: :get, as: :user_listing
      match '/findjobs',     to: 'listings#index',   via: 'get' 
      match '/users/:name/:id/edit', to: 'listings#edit', via: 'get'
      match '/:id/apply', to:  'listings#apply', via: 'get'

I appreciate your help!

Upvotes: 0

Views: 1079

Answers (2)

engineersmnky
engineersmnky

Reputation: 29308

While Coderhs has added something for you you also need to name that route so that you have a matcher for it like this:

 match '/:id/apply', to:  'listings#apply', via: 'get', as: :listing_apply

that way you will have access to the url helper listing_apply_path

also match and via is not needed you can just specify

get '/:id/apply', to: 'listings#apply', as: :listing_apply

match means any method (e.g. POST,GET,PUT,DELETE)

get means process GET requests.

match with :via means the same thing as get without it. I only use via in cases where I need 2 or more VERBS to got to the same place. Otherwise I just specify the method needed.

From http://guides.rubyonrails.org/routing

Routing both GET and POST requests to a single action has security implications. In general, you should avoid routing all verbs to an action unless you have a good reason to.

Update

You asked

Why do I need to tell routes here that I need the path as:listing_apply. Why didn't I have to do it for lets say the edit path?

the resources method creates these for you

resources :listings

generates following routes for you

listings     GET    /listings              listings#index
             POST   /listings/create       listings#create
new_listing  GET    /listings/new          listings#new
edit_listing GET    /listings/:id/edit     listings#edit
listing      GET    /listings/:id          listings#show
             PUT    /listings/:id          listings#update
             DELETE /listings/:id          listings#destroy

This will allow access to listings_path, new_listing_path, edit_listing_path, and listing_path. For the non named routes it uses the VERB (POST, PUT, DELETE) to determine routing

Upvotes: 2

coderhs
coderhs

Reputation: 4827

It should be

<li><%= link_to "Apply Now", listing_apply_path(id: @listing.id) %></li>

you need to pass in the instance variable into the path, using listing is undefined inside of the view.

Upvotes: 1

Related Questions