我有一个定量模型的Rails回调,它根据最近的活动更新一些数字,如:
class Data < ActiveRecord::Base
before_validation :check_numbers
def check_numbers
Check #1...
Check #2...
Check #3...
Check #4...
...etc.
end
所有这些检查加起来需要相当长的时间,通常是一秒的一小部分。
如果我有一个控制器动作,只对检查#4有任何影响-我如何才能避免检查 #1-3?例如,我可以传入一个像[4]这样的变量来告诉这个回调走捷径吗?
加分点:是否有一种方法可以方便地在服务器端上进行一些处理,在显示候选的下一个渲染页面之后?在后台执行需要在服务器端花费一些时间的任务可以通过延迟作业(https://github.com/tobi/delayed_job)来实现。
至于只做某一张支票。也许像下面这样
class Data < ActiveRecord::Base
before_validation :check_numbers
def check_numbers
check_one if to_check.includes? 1
check_two if to_check.includes? 2
check_three if to_check.includes? 3
check_four if to_check.includes? 4
...etc.
end
def to_check=(arr_or_checks)
@to_check = arr_or_checks
end
def to_check
@to_check
end
然后在你的控制器中,你可以指定需要检查什么,例如通过调用to_check([1, 3, 9])
。
这将为你的代码添加更多的处理,也将使控制器意识到它可能不应该的逻辑。为了避免这种信息泄漏,您应该使to_check方法私有,并在控制器使用的方法中设置它们,例如obj.do_x
和obj.do_y
可能在to_check
数组中设置不同的数字。
===== UPDATE ======
例子test = Data.find(33)
test.to_check = [1,4]
test.update_attributes(params[:test])
或test = Data.find(33)测试。To_check = [1,4]Test.name = "新名称"test.save
就像我说的,我不太喜欢在控制器中显式地这样做。因此,我将尝试将其封装在模型本身中,如下所示。
class Data
...
def update_attributes_by_admin(attributes)
to_check = [1,4]
update_attributes(attributes)
end
def update_attributes_by_reg_user(attributes)
to_check = [1,2,3,4,...] # use all numbers here.
update_attributes(attributes)
end
然后回到控制器我们可以这样做
def admin_action
...
test = Data.find(33)
test.update_attributes_by_admin(params[:test])
...
end
def reg_user_action
...
test = Data.find(33)
test.update_attributes_by_reg_user(params[:test])
...
end
当然,按照我在这个例子中所做的反向操作会更安全。例如
check_one unless not_to_check.includes? 1
,然后有not_to_check
方法而不是to_check
等。
这样,所有默认的保存/更新方法都将执行验证,而您创建的方法不执行完整的验证。
我认为这将是代码遗漏的东西
def to_check=(arr_or_checks)
@to_check = arr_or_checks
end
当你想使用它的时候,就像这样:
mod = Data.find(1)
mod.to_check = [1,4]
mod.save
这将保存并只检查1和4