相关守则:http://pastebin.com/EnLJUJ8G
class Task < ActiveRecord::Base
after_create :check_room_schedule
...
scope :for_date, lambda { |date| where(day: date) }
scope :for_room, lambda { |room| where(room: room) }
scope :room_stats, lambda { |room| where(room: room) }
scope :gear_stats, lambda { |gear| where(gear: gear) }
def check_room_schedule
@tasks = Task.for_date(self.day).for_room(self.room).list_in_asc_order
@self_position = @tasks.index(self)
if @tasks.length <= 2
if @self_position == 0
self.notes = "There is another meeting in
this room beginning at # {@tasks[1].begin.strftime("%I:%M%P")}."
self.save
end
end
end
private
def self.list_in_asc_order
order('begin asc')
end
end
我正在制作一个小型任务应用。每个任务都分配给一个房间。一旦我添加了一个任务,我想使用一个回调来检查在我刚刚添加的任务之前和之后是否在同一个房间里有任务(尽管我的代码现在只处理一个边缘情况)。
所以我决定使用after_create(因为如果他们编辑它,用户将手动检查它,因此不是after_save)所以我可以使用两个范围和一个类方法来查询当天,在房间里的任务,以及按时间排序。然后我在数组中找到对象并开始使用if语句。
我必须明确保存对象。有用。但我这样做感觉很奇怪。我不是太有经验(第一个应用程序),所以我不确定这是否是不满意或是否是惯例。我搜索了一堆并浏览了一本参考书,但我没有看到任何具体的内容。
感谢。
答案 0 :(得分:3)
对我来说,这似乎是before_create
的任务。如果您必须保存在after_*
回调中,则可能需要使用before_*
回调。
在before_create
中,您不必调用save
,因为保存在回调代码为您运行后发生。
而不是保存然后查询以查看是否有2个或更多对象返回,您应该查询一个在保存之前将发生冲突的对象。
在psuedo代码中,你现在拥有:
after creation
now that I'm saved, find all tasks in my room and at my time
did I find more than one?
Am I the first one?
yes: add note about another task, then save again
no: everything is fine, no need to re-save any edits
你应该拥有什么:
before creation
is there at least 1 task in this room at the same time?
yes: add note about another task
no: everything is fine, allow saving without modification
更像这样:
before_create :check_room_schedule
def check_room_schedule
conflicting_task = Task.for_date(self.day)
.for_room(self.room)
.where(begin: self.begin) # unsure what logic you need here...
.first
if conflicting_task
self.notes =
"There is another meeting in this room beginning at #{conflicting_task.begin.strftime("%I:%M%P")}."
end
end