为什么我的Rails 4范围显示为method_missing?

时间:2014-08-26 19:21:31

标签: ruby-on-rails-4

我确定我忽略了一些显而易见的事情,但是当我尝试调用它时,此模型中的示波器会产生method_missing错误。例如,在新的Rails控制台中,

 inspection = Inspection.find(1)
 inspection.created_before

 NoMethodError: undefined method `created_before`

我已经复制了Rails指南中的示例,希望我发出语法错误。我已经简化了它,因此它不需要变量。我评论了所有内容,但是类定义和范围没有区别。其他型号使用范围,但这个我没有看到我做错了什么。我已经将它定义为一个类定义,看看它是否但它不起作用。看来,这个类中的其他方法工作得很好。我整天都花在这上面,我没有看到它并寻求帮助。

inspection.rb

VARIANCE_ITEMS = 60
MISC_ITEMS = 70
REVIEW_ITEMS = [20, 30, 40, 50]


class Inspection < ActiveRecord::Base
  resourcify

  include RollbackLogger
  include SurveyHelper

  belongs_to :site
  belongs_to :survey

  has_many :scores, dependent: :destroy
  accepts_nested_attributes_for :scores

  has_one :cash_variance
  has_one :message, dependent: :destroy

  scope :created_before, -> { where("created_at < ?", Time.now) }
  scope :recent_of_same_type, ->(survey){ where(survey_id: survey.id).order("inspection_date desc").limit(5) }



  before_create do |inspection|
    begin
    inspection.name = Survey.find(inspection.survey_id).name

    rescue ActiveRecord::RecordNotFound
      inspection.name = 'blank'
    end
    unless inspection.inspection_date?
      inspection.inspection_date = inspection.created_at
    end
  end

  after_create do |inspection|
    items = Item.where(survey_id: inspection.survey_id)
    items.each do |item|
      Score.create(score_item: item.high_score, item_id: item.id, inspection_id:     inspection.id, multiplier: item.scoring)
    end
    survey = Survey.find(inspection.survey_id)
    if survey && survey.name == "Loss Prevention"
      REVIEW_ITEMS.each do |x|
        3.times do |score|
          Score.create!(item_id: ("#{x}#{score}").to_i, inspection_id: inspection.id, multiplier: 1)
        end
      end

    end

  end



protected

  def message_check
    actual_score = grand_total(self.scores, :score_item, :multiplier)
    hi_score = high_score_total(self.survey.items, :high_score)

    unless self.message.nil?
      if (actual_score < hi_score) && (self.message.emailed)
        self.message.update_attributes(flag: FLAGS[2]) if self.message
      elsif (actual_score < hi_score) && (self.message.emailed == false)
        self.message.update_attributes(flag: FLAGS[1]) if self.message
      else
        self.message.update_attributes(flag: FLAGS[0]) if self.message
      end
    end
  end

end

1 个答案:

答案 0 :(得分:1)

范围是在类级别而不是实例级别定义的。所以你的范围可以用

来调用
Inspection.created_before

scope只是class_method创建method,它将为您定义这些方法

scope :method_name,->(variables_accepted){method body}

转换为

class Inspection < ActiveRecord::Base
  def self.method_name(variables_accepted)
      method body
  end
end

这将返回之前创建的所有Inspection,这将是所有Inspection.scoped。与调用scope :created_before_id, ->(id){ where("created_at < ?", find(id).created_at)}

几乎相同

如果您想查找在特定实例之前创建的项目,可以将其范围设置为此

Inspection.created_before_id(1)

被称为

Inspection

这将返回在给定id 注意的创建日期之前创建的所有id,如果无法找到scope :created_before_id, ->(id){ inspection = find(id) inspection ? where("created_at < ?", inspection.created_at) : scoped } ,则会引发此问题。你可以像这样改变它

Inspection

如果给定id找不到Inspection,则会返回给定id之前的所有instance_methoddef created_before Inspection.where("created_at > ?", self.created_at) end s。

如果要从实例级别调用它,则需要定义Inspection,如此

Inspection.find(1).created_before

这将返回给定实例之前的所有{{1}},就像您现在所做的那样。

{{1}}