我对Rails相当陌生,我有一个Ruby on Rails 3.2应用程序,我已经集成了这里看到的Youtube_it gem https://github.com/kylejginavan/youtube_it。宝石工作良好,我能够将视频上传到youtube,但需要一段时间来处理视频。我想能够运行,作为一个后台工作,并将用户重定向到我所创建的感谢页面。
我不确定在哪里调用延迟方法。我想调用延迟方法,然后让用户重定向到page_path('thank you')页面。
任何帮助都将非常感激。我已经到处寻找答案了。
VideosControllerdef上传@video = video .create(params[:video])
if @video
@upload_info = Video.delay.token_form(params[:video], save_video_new_video_url(video_id: @video.id))
else
respond_to do |format|
format.html { render "/videos/new" }
end
end
end
def save_video
@video = Video.find(params[:video_id])
if params[:status].to_i == 200
@video.update_attributes(youtube_id: params[:id].to_s, is_complete: true, user_id: current_user.id, approved: false)
Video.delete_incomplete_videos
else
Video.delete_video(@video)
end
#redirect_to videos_path, notice: "video successfully uploaded"
redirect_to page_path('thank-you')
end
这是我的控制器。
class VideosController < ApplicationController
before_filter :authenticate_user!, only: [:new, :upload, :save_video, :destroy]
def index
if params[:category]
Video.yt_session
@videos = Video.approved.where(category_id: params[:category])
else
Video.yt_session
@videos = Video.approved
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: @videos }
end
end
def show
@video = Video.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @video }
end
end
def new
@video =Video.new
@categories = Category.all
respond_to do |format|
format.html # new.html.erb
format.json { render json: @video }
end
end
def upload
@video = Video.create(params[:video])
if @video
@upload_info = Video.token_form(params[:video], save_video_new_video_url(video_id: @video.id))
else
respond_to do |format|
format.html { render "/videos/new" }
end
end
end
def save_video
@video = Video.find(params[:video_id])
respond_to do |format|
if @video.update_attributes(:youtube_id => params[:id].to_s, :is_complete => true,:user_id=>current_user.id,:approved=>false)
format.html { redirect_to page_path('thank-you') }
format.json { head :no_content }
else
format.html { Video.delete_video(@video) }
format.json { render json: @category.errors, status: :unprocessable_entity }
end
end
end
def destroy
@video = Video.find(params[:id])
if Video.delete_video(@video)
flash[:notice] = "Video deleted."
else
flash[:error] = "We were unable to delete this video."
end
redirect_to videos_path
end
def vote_up
@video = Video.find(params[:id])
@video.update_attribute(:votes_up, (@video.votes_up.to_i + 1))
redirect_to @video
end
protected
def collection
@videos ||= end_of_association_chain.completes
end
end
你总是可以使用后台工作者来做,使用delayed_job,但个人而言,我更喜欢使用Resque/beanstald/RabbitMQ,因为我可以同时运行多个工作者。
为了使您的生活更轻松,您只需尝试Sidekiq (https://github.com/mperham/sidekiq)。
你将把你的worker逻辑移到某个worker中。
包含Sidekiq到你的Gemfile
gem 'sidekiq'
在控制器中添加如下内容:
VideoSaverWorker.perform_async(@video.id)
VideoSaverWorker必须看起来像:
class VideoSaverWorker
include Sidekiq::Worker
sidekiq_options queue: "high"
def perform(video_id)
video = Video.find(video_id)
.....
.....
end
end
请注意,使用此方法您将在后台线程中完成工作,但它不会将您重定向到相关页面。
你需要做一些变通,比如定期刷新页面,直到你在你的视图html页面上看到更改,或者你可以使用Faye或Node.js将更改推送到你的网页。