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

Posted

技术标签:

【中文标题】如何从另一个模型中检索嵌套模型数据? : 未定义的方法错误【英文标题】:How to retrieve nested model data from another model? : undefined method error 【发布时间】:2015-12-16 12:53:19 【问题描述】:

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

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

【问题讨论】:

你能发布完整的错误信息吗? but it throws error - 当您在应用程序中遇到错误并提出 SO 问题时,您应该始终将完整的错误消息与堆栈跟踪一起包含在内。从您发布的内容来看,您似乎在某处错过了new,而您正在致电Calendar(params)。要知道您需要检查堆栈跟踪的第一行的确切位置。那是假设您的错误实际上是在说Calendar,而不是calendar。不过我感觉是calendar,完整的消息是undefined method calendar for NilClass,对吗? 请在帖子中也包含您的模型,很明显错误来自模型。 我现在编辑了我的帖子以包含模型。完整的错误消息是:NoMethodError in EventsController#new undefined method `Calendar' for #<0x63df0b0> 【参考方案1】:

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

【讨论】:

以上是关于如何从另一个模型中检索嵌套模型数据? : 未定义的方法错误的主要内容,如果未能解决你的问题,请参考以下文章

Django:相互嵌套序列化程序

cakephp从另一个表中将数据检索到控制器中

如何在sequelize中对嵌套模型中的列进行排序?

如何在没有模型的情况下验证 MVC3 中的强类型视图

发生错误时如何在嵌套模型中填充表单?

查看多个模型(不是表单)时的嵌套属性