【问题标题】:Issue with uploading using CarrierWave_Direct使用 CarrierWave_Direct 上传的问题
【发布时间】:2016-06-20 11:01:36
【问题描述】:

我对 ruby​​ 和 rails 还很陌生,使用carrierwave_direct 上传时遇到了一些问题。我跟着 Ryan Bates 的 Railscast 383 使用carrierwave_direct 上传。但是,他提供的解决方案似乎对我不起作用。我有一个使用 Devise 创建的用户模型,并且我有一个上传器来处理我的上传。我正在尝试使用上传器上传视频文件,我计划稍后使用带有 AWS API 的 Elastic Transoder 进行转码。这些文件正在上传到 s3,但似乎它们没有与我的数据库中的记录相关联。文件在我提交后立即上传,但我需要一种方法来创建它们以及标题、描述、以及以后可能的其他参数。我的 if-else 语句也总是重定向到我的 else 语句。我认为我的问题出在我的控制器上;我的路线和视图似乎运行良好,我只是被困在这个问题上。

进一步澄清:我需要用户能够上传视频,然后让用户输入标题、描述等,然后被重定向到另一个页面。然后我需要能够在稍后被调用时显示该文件。

这是我的 UploadsController:

class UploadsController < ApplicationController
before_action :authenticate_user!, only: [:create, :destroy]
before_action :current_user, only: :destroy

  def index
    @uploader = Upload.new.video
    @uploader.success_action_redirect = new_uploads_url
  end

  def show
    @upload = Upload.find(params[:id])
  end

  def new
    @upload = Upload.new(key: params[:key])
  end

  def create
    @upload = Upload.new(upload_params)
      if @upload.save
      redirect_to home_index_path
      return
    else
      redirect_to uploads_index_path
    end
  end

  def edit
  end

  def destroy
    @upload = Upload.find(params[:id])
    @upload.destroy
    flash[:notice] = "Upload deleted"
    redirect_to request.referrer || root_url
  end


  def upload_params
    params.require(:upload).permit(:video, :title, :description)
  end
end

这是我的上传模型:

class Upload < ActiveRecord::Base
  belongs_to :user
  default_scope -> { order(created_at: :desc) }
  validates :user_id, presence: true
  validates :description, presence: true
  validates :title, presence: true, length: {maximum: 100}
  validates :description, presence: true
  validates :video, presence: true
  mount_uploader :video, VideoUploader

  after_save :enqueue_video

  def enqueue_video
    VideoWorker.perform_async(id, key) if key.present?
  end

 class VideoWorker
    include Sidekiq::Worker

    def perform(id, key)
     upload = Upload.find(id)
     upload.key = key
     video.remote_video_url = upload.video.direct_fog_url(with_path: true)
     upload.save!
    end
 end
end

还有我的路线:

Rails.application.routes.draw do

  get '/home/index'

  root 'home#index'

  devise_for :users

  get 'users/:id' => 'users#show'

  resources :uploads

  get '/index' => 'uploads#index'

end

编辑这也是我的用户控制器和用户显示页面:

控制器: 类用户控制器

  def show 
    @user = User.find(params[:id])
  end

end

显示:

<h1><%= @user.username %></h1>

<h3>Title:</h3>
<%= @upload.title %>

【问题讨论】:

  • 我怀疑@upload 存在验证错误。您是否在某处显示@upload.errors?如果不是,它的价值是什么?
  • 所以,你对验证是正确的。我没有任何验证测试,所以我只是删除了验证,尝试另一个文件上传,然后重定向工作。但是,当我尝试访问 @upload 时,它没有显示在用户显示页面上。记录的信息没有被放入我的数据库吗?或者可能是别的什么?
  • 很难说;如果@upload.save 返回true,那么它可能已保存到数据库中。通过使用来自rails consoleUpload.last 之类的内容,确保它确实。记录可能在数据库中,但由于您删除了所有验证,因此缺少 user_id。删除验证不是修复,查看错误是什么并修复 that 是修复:-) 您也可能在控制器呈现显示或视图代码时出错。
  • 我编辑了原始问题,并将 UsersController 和 Users Show 页面也放了上去。我只是想测试验证是否是阻止我重定向的原因。我添加了 user_id 验证,但重定向失败。我只是在这个问题上迷路了。
  • 在控制台中运行您推荐的命令后,它返回了我上次上传的文件!那么,这可能是我的 User Show 的视图/控制器问题吗?

标签: ruby-on-rails ruby file-upload amazon-s3 carrierwave


【解决方案1】:

问题是你在做:

def create
    @upload = Upload.new(upload_params)
    # [..]
end

def upload_params
    params.require(:upload).permit(:video, :title, :description)
end

您的UploadUser 相关联:

class Upload < ActiveRecord::Base
    belongs_to :user
    validates :user_id, presence: true
    # [..]
end

那么Rails 是如何知道哪个Upload 属于哪个User?你从来没有告诉过Upload 任何关于User 的事情!

如果你总是想使用当前登录的用户,你可以这样做:

def create
    @upload = Upload.new(upload_params)
    @upload.user = current_user
    # [...]
end

当然,这假设current_user 是获取当前登录用户的正确方法(通常是这样)。

如果您希望能够将其连接到任何其他用户,则需要在其中添加一个user_id 字段并将其添加到upload_params

【讨论】:

  • 就是这样!我现在让用户与上传无缝关联!这是我第一次在 Stack Overflow 上提问,你太棒了!我应该能够从这里弄清楚。哈哈希望。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多