nil的未定义方法:NilClass - Controller

时间:2012-02-29 11:22:23

标签: ruby-on-rails-3 ruby-on-rails-3.1

有些人可以向我解释为什么每次尝试创建预订时我都会收到以下错误。

NoMethodError in BookingsController#create

undefined method `diary_slot_day_time_path' for nil:NilClass

我的控制器中有以下代码:

class BookingsController < PortalController

  # GET /bookings
  # GET /bookings.json
  def index

    session[:booking_context] = 'index'

    if current_user.is_booking_manager? 
    #  @bookings = Booking.all
    # @bookings = Booking.filter(params[:search], [:reference_number, :company_id])
     @bookings = Booking.includes(:company).filter(params[:search], [:reference_number, "companies.name"])
    @main_heading = 'Bookings'
    else
      @bookings = current_user.company.bookings
    @main_heading = "#{current_user.company.name} Bookings"
    end

    respond_to do |format|
      format.html # index.html.erb
    end
  end

  # GET /bookings/1
  def show
    @booking = Booking.find(params[:id])
    goto_booking(@booking)
  end

  # GET /bookings/1/edit
  def edit
    @booking = Booking.find(params[:id])
    @main_heading = 'Edit Booking'
  end

  # Go to booking
  def goto_booking(booking)

    site = @booking.site
    slot_day = @booking.slot_day
    slot_time = @booking.slot_time

    # don't need to check slot_time because it is optional
    if session[:booking_context] and session[:booking_context] == 'diary' and site and slot_day
      # Go the diary page
      respond_to do |format|
        format.html { redirect_to diary_slot_day_time_path(site, slot_day, slot_time) }
      end
    else

      # Go to booking edit page
      respond_to do |format|
        format.html { redirect_to edit_booking_path(@booking) }
      end
    end
  end

  # POST /bookings
  def create
    @booking = Booking.new(params[:booking])
    unless @booking and @booking.slot_time and @booking.slot_time.number_of_free_slots > 0
      flash[:notice] = 'Slot no longer available'
      redirect_to :back
      return
    end

    if @booking.save
      flash[:notice] = 'Booking was successfully created'
      goto_booking(@booking)
    else
      @main_heading = 'Review New Booking'
      respond_to do |format|
        format.html { render action: "new" }
      end
    end
  end

  # PUT /bookings/1
  def update
    @booking = Booking.find(params[:id])
    if @booking.update_attributes(params[:booking])
      flash[:notice] = 'Booking was successfully updated'
      goto_booking(@booking)
    else
      @main_heading = 'Review Booking'
      respond_to do |format|
        format.html { render action: "edit" }
      end
    end
  end

  def confirmation
    begin
      @booking = Booking.find(params[:booking][:id])
      @booking.update_attributes(params[:booking])
      if params[:make_unexpected]
        @booking.provisional_appointment = nil
        @booking.save!
      end
      @booking.update_slot!
      success = true
    rescue => e
      flash[:error] = e.message
      success = false
    end

    if success
      flash[:notice] = 'Booking confirmed'
      respond_to do |format|
        format.html { redirect_to booking_path(@booking) }
      end      
    else
      redirect_to :back
    end
  end

  # DELETE /bookings/1
  def destroy
    @booking = Booking.find(params[:id])

    if @booking
      if session[:booking_context] and session[:booking_context] == 'diary'
        site = @booking.site
        slot_day = @booking.slot_day
        slot_time = @booking.slot_time
      end

      if @booking.destroy
        flash[:notice] = 'booking removed'
      else
        flash[:error] = 'could not remove booking'
      end
    end

    # don't need to check slot_time; that's optional
    if site and slot_day

      # redirect to diary page
      respond_to do |format|
        format.html { redirect_to diary_slot_day_time_path(site, slot_day, slot_time) }
      end
    else

      # redirect to booking index
      respond_to do |format|
        format.html { redirect_to bookings_url }
      end
    end
  end

  def diary_slot_day_time_path(*args)
    @template.diary_slot_day_time_path(*args)
  end

end

我认为这可能与路由错误有关,我可能错了。这是我的完整跟踪错误:Pastie。我查看了跟踪信息,告诉我我的go_to_bookingcreate方法存在问题。

1 个答案:

答案 0 :(得分:1)

为什么在控制器的底部定义了这个方法?

def diary_slot_day_time_path(*args)
  @template.diary_slot_day_time_path(*args)
end

这是试图引用一个名为@template的未定义实例变量,这就是你收到错误的原因。

您应该在路线中定义此方法,方法是使用以下嵌套路线:

match '/diary/:day/:time', :to => "some_controller#some_action", :as => "diary_slot_day_time"