I've had a problem over the last few days getting my nested resources to create and display properly. There are tons of similar questions on StackOverflow and lots of blog posts on this, but they all seem to either deal with a older version of Rails or a different issue. I'm at the point where once I finally fix something, another error pops up. I've narrowed it down to me making a stupid mistake or typo being too inexperienced to notice.
I have a Jobs model that belongs to a Venue model.  The venue works fine and I've even gotten as far as to be able to go to my nested Jobs index under each Venue and bring up the New and Edit forms, but going to 'Show' or creating a new Job caused an undefined method error.  After a lot of searching I found plenty with the same problem and tried to implement their fixes, but now I'm getting a Routing Error.
Most of my confusing comes from when to leave off the @, when to use :venue_id instead of :id in params, etc. Every example I see seems to have a different way and I can't seem to make any of them work for me.
Any bump in the right direction would be extremely helpful.
The Routing Error
No route matches {:action=>"show", :controller=>"jobs", :venue_id=>#<Venue id: 1, name: "Burger Chef", city: "Chicago", state: "Illinois", areacode: 60614, created_at: "2013-02-05 21:33:41", updated_at: "2013-02-06 23:01:05", avatar_file_name: nil, avatar_content_type: nil, avatar_file_size: nil, avatar_updated_at: nil>}
routes.rb
Twist::Application.routes.draw do
  resources :users
  devise_for :users
  resources :venues do
    resources :jobs
  end
end
jobs_controller.rb
class JobsController < ApplicationController
  # GET /jobs
  # GET /jobs.json
  before_filter :get_venue
  def get_venue
    @venue = Venue.find(params[:venue_id])
  end
  def index
    @jobs = @venue.jobs
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @jobs }
    end
  end
  # GET /jobs/1
  # GET /jobs/1.json
  def show
    @job = @venue.job.find(params[:id])
    if params[:id]
      @venue = Venue.where(:id => params[:id]).first
      @jobs = @venue.job_url
    else
      @jobs = Jobs.all
    end
    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @job }
    end
  end
  # GET /jobs/new
  # GET /jobs/new.json
  def new
    @job = @venue.jobs.build
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @job }
    end
  end
  # GET /jobs/1/edit
  def edit
    @job = @venue.job.find(params[:venue_id])
  end
  # POST /jobs
  # POST /jobs.json
  def create
    @job = @venue.jobs.new(params[:job])
    respond_to do |format|
      if @job.save
        format.html { redirect_to :action => :show, :id => @venue.id, 
                      notice: 'Job was successfully created.' }
        format.json { render json: [@venue, @job],
                             status: :created, 
                             location: [@venue, @job] }
      else
        format.html { render action: "new" }
        format.json { render json: @job.errors, status: :unprocessable_entity }
      end
    end
  end
  # PUT /jobs/1
  # PUT /jobs/1.json
  def update
    @job = Job.find(params[:id])
    respond_to do |format|
      if @job.update_attributes(params[:job])
        format.html { redirect_to @job, notice: 'Job was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @job.errors, status: :unprocessable_entity }
      end
    end
  end
  # DELETE /jobs/1
  # DELETE /jobs/1.json
  def destroy
    @job = Job.find(params[:id])
    @job.destroy
    respond_to do |format|
      format.html { redirect_to jobs_url }
      format.json { head :no_content }
    end
  end
end
venues_controller.rb
class VenuesController < ApplicationController
  # GET /venues
  # GET /venues.json
  def index
    @venues = Venue.all
    if params[:name]
      @user = User.where(:name => params[:name]).first
      @venues = @user.venues
    end
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @venues }
    end
  end
  # GET /venues/1
  # GET /venues/1.json
  def show
    @venue = Venue.find(params[:id])
    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @venue }
    end
  end
  # GET /venues/new
  # GET /venues/new.json
  def new
    @venue = Venue.new
    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @venue }
    end
  end
  # GET /venues/1/edit
  def edit
    @venue = Venue.find(params[:id])
    #if session[:user_id] != @venue.user_id
    #  flash[:notice] = "Sorry, you cannot edit this venue."
    #  redirect_to(venues_path)
    # =>end
  end
  # POST /venues
  # POST /venues.json
  def create
    @venue = Venue.new(params[:venue_id])
    respond_to do |format|
      if @venue.save
        format.html { redirect_to @venue, notice: 'Venue was successfully created.' }
        format.json { render json: @venue, status: :created, location: @venue }
      else
        format.html { render action: "new" }
        format.json { render json: @venue.errors, status: :unprocessable_entity }
      end
    end
  end
  # PUT /venues/1
  # PUT /venues/1.json
  def update
    @venue = Venue.find(params[:id])
    respond_to do |format|
      if @venue.update_attributes(params[:venue])
        format.html { redirect_to @venue, notice: 'Venue was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @venue.errors, status: :unprocessable_entity }
      end
    end
  end
  # DELETE /venues/1
  # DELETE /venues/1.json
  def destroy
    @venue = Venue.find(params[:id])
    @venue.destroy
    respond_to do |format|
      format.html { redirect_to venues_url }
      format.json { head :no_content }
    end
  end
end
job.rb
class Job < ActiveRecord::Base
  attr_accessible :description, :name, :requirement, :venue_id
  validates :name, :presence => true, :length => { :minimum => 3 }
  belongs_to :venue
end
venue.rb
class Venue < ActiveRecord::Base
  attr_accessible :areacode, :avatar, :city, :name, :state
  has_many :jobs
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }
end
/jobs/show.html.erb
<p id="notice"><%= notice %></p>
    <% @job = Job.find(param[:venue_id]) %>
    <p>
      <b>Name:</b>
      <%= @job.name %>
    </p>
    <p>
      <b>Company:</b>
      <p><%= @venue.name %></p>
      <p><%= link_to @job.venue.name, venue_path(@venue) %></p>
    <p>
      <b>Job:</b>
      <%= @job.job_id %>
    </p>
    <p>
      <b>Description:</b>
      <%= @job.description %>
    </p>
    <p>
      <b>Requirement:</b>
      <%= @job.requirement %>
    </p>
    <%= link_to 'Edit', edit_venue_job_path(@venue, @job) %> |
    <%= link_to 'Back', venue_jobs_path(@venue, @job) %>
**/jobs/index.html.erb**
<div class="usergrid">
  <% jobs = @venue.jobs %>
  <% @venue.jobs.each do |job| %>
<div class = "user venue">
    <p>
        <h2><%= link_to job.name, venue_job_path(@venue) %></h2>
        <%= link_to 'Edit', edit_venue_job_path(@venue, job) %><br/>
        <%= link_to 'Delete', venue_jobs_path(@venue, @job), :confirm => 'Are you sure?', :method => :delete %>
</div>
<% end %>
<div style="clear:both"></div>
</div>
<%= link_to 'New Job', new_venue_job_path(@venue) %>
I realize that...
I've tried messing with the routes, changing the actual links and routes, messing with scope, and as many of the common fixes for these errors that I could find and none of them seemed to help.
Thanks!
The error is saying that there is no route for the given params :
{:action=>"show", :controller=>"jobs", :venue_id=> "an_id"}
You can check that by running rake routes, and you'll see that, as jobs is nested under venue, the jobs#show controller actions needs two parameters : the venue_id (which is the job's 'parent') and the id which is the job id.
I quickly checked your code, and I think that one one of the things that causes the error is this line :
<h2><%= link_to job.name, venue_job_path(@venue) %></h2>
this should be
<h2><%= link_to job.name, venue_job_path(@venue, @job) %></h2>
Basically you'll get that kind of error, whenever you'll try to render a link to a job without providing the venue.
Let me know if you need more details or more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With