所以到目前为止,我的代码基础是:
客户has_one
日历
日历belongs_to
客户
日历has_many
活动
事件belongs_to
日历
我正在尝试,在创建新事件时,指定它所属的客户和日历,但它会抛出错误“未定义的方法`日历'”:
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
答案 0 :(得分: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
方法获取变量。每个动作都有自己的独立变量,因此在使用之前一定要准备好所有必要的变量。