我在我的Controller
课程中使用了类似的内容:
before_action :do_something, only: [:new, :create]
def new
@myModel = MyModel.new
end
def create
@myModel = MyModel.create_with_data(params)
respond_to do |format|
if @myModel.errors.empty?
format.html { redirect_to @myModel, notice: 'MyModel was successfully created.' }
format.json { render :show, status: :created, location: @myModel }
else
logger.error 'MyModelController: Creating mymodel failed!'
format.html { render :new }
format.json { render json: @myModel.errors, status: :unprocessable_entity }
end
end
def do_something
# Very long method
end
现在,问题是,我的do_something
方法需要很长时间才能执行。如果用户在创建新的myModel
字段时会出错,他将需要等待此方法执行,只是为了向他显示一些错误。
让我们说,我不想要前端验证,我不能减少do_something
方法的时间。如何从调用do_something
方法之前执行的new
以某种方式传递数据,因此在create
方法之前不需要再次执行?
答案 0 :(得分:3)
我会考虑使用乐观的储蓄方法。就像通常如何处理未经证实的用户一样。
您在数据库中插入记录,但设置的状态表示它不是完整的记录。然后在确认时更新记录。
它为用户提供快速反馈,您可以让您的网络流程免于等待do_something
。
class MyModel < ActiveRecord::Base
# create an Int column named status
# make sure it has an index and defaults to 0.
enum status: [:unverified, :verified]
end
所以,你会在你的控制器中做这样的事情:
def create
# Don't do params assignment / whitelisting in your models.
# models should not be aware of parameters.
@my_model = MyModel.new(my_model_params) do |m|
# This should be handled by the DB default but
# this is a belt and suspenders approach to be 200% sure
# that a record does not slip through.
m.unverified!
end
if @my_model.save
MyModelVerificationJob.perform_later(@my_model)
respond_to do |format|
format.html do
flash[:notice] = "We are currently verifying..."
redirect_to :edit, @my_model
end
# ...
end
else
# we already know something is fishy so just render the
# form again.
respond_to do |format|
# ...
end
end
end
private
def my_model_params
params.require(:my_model).permit(...)
end
此示例使用Rails 5 Active Jobs,但您也可以查看Resque或Sidekiq。
如何准确处理do_something
方法的回调取决于所需的用户交互类型。例如,如果用户需要更正表单,则会缓存后台作业的结果,并提示用户访问他们更正表单的页面。