2015-12-16 28 views
0

所以我的代碼的基礎到目前爲止是:如何從另一個模型中檢索嵌套的模型數據? :未定義的方法錯誤

客戶has_one日曆

日曆belongs_to客戶

日曆has_many事件

事件belongs_to日曆

我想在創建新事件時指定客戶和日曆ongs到,但它拋出錯誤「未定義的方法'日曆'」:

class EventsController < ApplicationController 

    def new 
    @event = Event.new 
    @currentcalendar = current_customer.calendar # this is where it is failing 

    end 

    def create 
    if @event = @currentcalendar.build.event(event_params) 
     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 
end 

這是application_controller內我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 

下面是相關的控制器文件。顧客:

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 

日曆:

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 

我非常新的Ruby/Rails,因此不能由我自己想出解決辦法。發生此問題是因爲我錯誤地創建了我的日曆嗎?我希望在用戶創建時創建它,這是可行的,但我不知道如何訪問事件控制器中的日曆和用戶。

感謝您的幫助!

編輯:這些是模型類。

客戶:

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 

日曆:

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


end 

事件:

class Event < ActiveRecord::Base 
    belongs_to :calendar 

end 
+1

你能發佈完整的錯誤信息嗎? – brito

+3

'但是它會拋出錯誤 - 當你在應用程序中發生錯誤,並且你在問這個問題時,你應該總是包含完整的錯誤信息和一個堆棧跟蹤。從你發佈的內容看來,你似乎錯過了某處的'new',並且你正在調用'Calendar(params)'。要知道你到底需要檢查堆棧跟蹤的第一行。這是假設你的錯誤是真的說'日曆',而不是'日曆'。儘管我有一種感覺,那就是「日曆」,完整的消息將是'NilClass'的未定義方法日曆,是不是? – BroiSatse

+0

請在你的帖子中加入你的模型,很明顯,錯誤來自模型。 – mudasobwa

回答

0

current_customer可以nil在倍。爲避免這種情況,您可以添加一個before_filter回調函數,用於檢查是否存在已登錄的客戶。

在你application_controller創建一個名爲customer_found?

def customer_found? 
    current_customer.present? 
end 

更改您的活動控制方法

class EventsController < ApplicationController 
    before_filter :customer_found? 
    before_filter :prepare_calendar, only: [:new, :create] 

    def new 
    @event = Event.new  
    end 

    def create 
    if @event = @current_calendar.build.event(event_params) 
     redirect_to '/main' 
    else 
     redirect_to '/compose' 
    end 
    end 

    private 

    def prepare_calendar 
    @current_calendar = current_customer.calendar 
    end 

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

既然你沒有指派你@current_calendar在你創建方法,那麼你會得到undefined method build for nil class。您需要初始化該變量,因爲它無法從new方法中獲取它。每個動作都有自己的獨立變量,因此在使用它們之前一定要準備好所有必要的變量。