我确定我忽略了一些显而易见的事情,但是当我尝试调用它时,此模型中的示波器会产生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
答案 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_method
或def created_before
Inspection.where("created_at > ?", self.created_at)
end
s。
如果要从实例级别调用它,则需要定义Inspection
,如此
Inspection.find(1).created_before
这将返回给定实例之前的所有{{1}},就像您现在所做的那样。
{{1}}