如何从另一个模型中检索嵌套模型数据? :未定义的方法错误

时间:2015-12-16 12:53:20

标签: ruby-on-rails ruby associations rails-activerecord

所以到目前为止,我的代码基础是:

客户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

1 个答案:

答案 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方法获取变量。每个动作都有自己的独立变量,因此在使用之前一定要准备好所有必要的变量。