-1

I'm getting a bit confused as to why I am receiving this error as (i think) it is suggesting that my current_customer returns nil. I do not know how to fix this, is it a problem with my current_customer method, sessions controller, or my events_controller...

Event Model:

class Event < ActiveRecord::Base
  belongs_to :calendar

end

Events Controller:

class EventsController < ApplicationController

  def new
    @event = Event.new
    @calendar = current_customer.calendar #WHY IS IT NOT ERRORING HERE TOO?

  end


  def create

    **@calendar = current_customer.calendar #IT IS CALLING ERROR HERE**
    @event = @calendar.build.event(event_params)
    if @event.save
      redirect_to '/main'
    else
      redirect_to '/compose'
    end
  end


  private
  def event_params
    params.require(:event).permit(:calendar_id, :name, :starts_at, :ends_at) 
  end

Customer model:

class Customer < ActiveRecord::Base
  belongs_to :business
  has_one :calendar

  has_secure_password

  attr_accessor :remember_token

  #remembers a user in the database for  use in persistent sessions
  def remember
    self.remember_token = Customer.new_token
    update_attribute(:remember_digest, Customer.digest(remember_token))
  end

  def Customer.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
        BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

  def forget
    update_attribute(:remember_digest, nil)
  end

  def Customer.new_token
    SecureRandom.urlsafe_base64
  end

  #returns true if the given token matches the digest
  def authenticated?(remember_token)
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end


end

Customer controller:

class CustomersController < ApplicationController

  def new

    @customer = Customer.new
    @businesses = Business.all
    @calendar = Calendar.new

  end

  def create

    @customer = Customer.create(customer_params)

    @calendar = @customer.build_calendar
    @customer.save!
    session[:customer_id] = @customer.id

    redirect_to '/'
  rescue ActiveRecord::RecordInvalid => ex
    render action: 'new', alert: ex.message
  end

  private
  def customer_params
    params.require(:customer).permit(:first_name, :last_name, :business_no, :email, :password, :business_id)
  end

end

Sessions controller:

class SessionsController < ApplicationController

  def new

  end

  def create
    @customer = Customer.find_by_email(params[:session][:email])
    if @customer && @customer.authenticate(params[:session][:password])
      session[:customer_id] = @customer.id #log in
      @customer.remember
      cookies.permanent.signed[:customer_id] = @customer.id
      cookies.permanent[:remember_token] = @customer.remember_token
      redirect_to '/main'
    else
      #need to add flash error: invalid password/email combination
      redirect_to '/login'
    end
  end

  def destroy
    @current_customer.forget
    cookies.delete(:customer_id)
    cookies.delete(:remember_token)
    session.delete(:customer_id)
    @current_customer = nil
    redirect_to '/'
  end
end

Current_customer method within application.controller:

helper_method :current_customer

  def current_customer
    if (customer_id = session[:customer_id])
      @current_customer ||= Customer.find_by(id: customer_id)
    elsif (customer_id = cookies.signed[:customer_id])
      customer = Customer.find_by(id: customer_id)
      if customer && customer.authenticated?(cookies[:remember_token])
        session[:customer_id] = customer.id #log in
        @current_customer = customer

      end
    end
  end

Calendar model:

class Calendar < ActiveRecord::Base
  belongs_to :customer
  has_many :events

end

calendars_controller:

class CalendarsController < ApplicationController

  def new
    @calendar = Calendar.new(calendar_params)

  end

  def create
    @calendar = Calendar.new(calendar_params)
  end

private
  def calendar_params
    params.require(:customer_id)
  end

end

I am new to Ruby/Rails so I would really appreciate any explanations and answers, please help! thanks

K M Rakibul Islam
  • 33,760
  • 12
  • 89
  • 110
Sarahshuffle
  • 182
  • 2
  • 11

2 Answers2

1
@calendar = current_customer.calendar
@event = @calendar.build.event(event_params)

According to the error message, @calendar is nil, so when you call @calendar.build.event(event_params) in the next line, it calls: nil.build and hence you get the error.

For some reason, your current_customer's calendar is nil for that request. Figure that out and make sure the current_customer has a calendar present in the database, then it should work.

Also, you need to change:

@event = @calendar.build.event(event_params)

To:

@event = @calendar.events.build(event_params)
K M Rakibul Islam
  • 33,760
  • 12
  • 89
  • 110
  • ok, I realised I was testing it on an old customer. Now calendar is not nil, but I am still getting the error: NoMethodError in EventsController#create undefined method `build' for # on the same line. Is this a syntax error? – Sarahshuffle Dec 16 '15 at 16:43
  • Try: `@calendar.events.build(event_params)`. – K M Rakibul Islam Dec 16 '15 at 16:45
0

It would seem that @calendar is nil in the events controller.

Start by checking the current_customer passes back the customer you were expecting.

Then check that the current_customer has a calendar created for you to reference.

P3rishable
  • 83
  • 10
  • ok, silly me I was testing it on an old customer which was created before I had implemented calendars. Now the error has changed to NoMethodError in EventsController#create undefined method `build' for # Is this a syntax error? – Sarahshuffle Dec 16 '15 at 16:42
  • Take a look at this post. I think your syntax is a bit off http://stackoverflow.com/a/4954542/5441472 ``` @event = @calendar.event.build(event_params) ``` – P3rishable Dec 17 '15 at 13:09