我有一个sidekiq作业,需要在提交后运行以避免a common race condition。
class User < ActiveRecord::Base
...
after_commit do |user|
if @enqueue_some_job
SomeJob.new(user).enqueue
@enqueue_some_job = nil
end
end
def verify
@enqueue_some_job = ...
...
save!
end
end
代码有点难看。我更愿意以某种方式将回调内联包装成这样:
class User < ActiveRecord::Base
def verify
if ...
run_after_commit do |user|
SomeJob.new(user).enqueue
end
end
...
save!
end
end
Rails中是否存在任何内容以支持这样的语法(不依赖于设置临时实例变量)?或者是否存在任何扩展Rails的库以添加这样的语法?
答案 0 :(得分:1)
使用关注点找到解决方案。片段得到了足够的重用,它可能是抽象实例变量并形成可重用模式的更好选择。它不会处理返回(不确定哪些是通过#include <stdio.h>
#include <string.h>
#include <ctype.h>
void rek(char array[], int d)
{
int counter=0;
if(d==0)
{
printf("%s \n",array);
printf("%d \n",counter);
}
else
{
if((array[d]>='A' && array[d]<='Z')&&(array[d-1]>='A' && array[d-1]<='Z'))
{
array[d]=array[d]+32;
array[d-1]=array[d-1]+32;
counter++;
rek(array,d-2);
}
if((array[d]>='a' && array[d]<='z')&&(array[d-1]>='a' && array[d-1]<='z'))
{
array[d]=array[d]-32;
array[d-1]=array[d-1]-32;
counter++;
rek(array,d-2);
}
}
}
int main()
{
char array[100];
int d;
gets(array);
d=strlen(array);
rek(array,d);
return 0;
}
支持的,因为没有事务可以回滚。
应用/模型/关切/ callbackable.rb 强>
after_commit
应用/模型/ user.rb 强>
module Callbackable
extend ActiveSupport::Concern
included do
after_commit do |resource|
if @_execute_after_commit
@_execute_after_commit.each do |callback|
callback.call(resource)
end
@_execute_after_commit = nil
end
end
end
def execute_after_commit(&callback)
if callback
@_execute_after_commit ||= []
@_execute_after_commit << callback
end
end
end
答案 1 :(得分:0)
在声明回调时,您可以使用方法名称而不是块:
class User < ActiveRecord::Base
after_commit :do_something!
def do_something!
end
end
要在回调中设置条件,您可以使用if
和unless
选项。请注意,这些只是哈希选项 - 而不是关键字。
您可以使用方法名称或lambda:
class User < ActiveRecord::Base
after_commit :do_something!, if: -> { self.some_value > 2 }
after_commit :do_something!, unless: :something?
def do_something!
end
def something?
true || false
end
end
答案 2 :(得分:-1)
假设您需要在创建后验证用户。
after_commit :run_sidekiq_job, on: :create
after_commit :run_sidekiq_job, on: [:create, :update] // if you want on update as well.
这将确保您的作业仅在提交db。
之后运行然后定义必须执行的工作。
def run_sidekiq_job
---------------
---------------
end
希望它可以帮助你:)