Ruby on rails 添加amazon s3的carrierwave初始值设定项后无法启动rails应用程序

Ruby on rails 添加amazon s3的carrierwave初始值设定项后无法启动rails应用程序,ruby-on-rails,ruby,ruby-on-rails-4,amazon-s3,carrierwave,Ruby On Rails,Ruby,Ruby On Rails 4,Amazon S3,Carrierwave,我正在尝试创建一个rails应用程序,使用carrierwave将文件上传到S3。我按照以下说明操作:。因为本地上传工作正常。但是当涉及到S3时,它抛出了以下错误: bin/rails:6: warning: already initialized constant APP_PATH /Users/sancowinx/Code/rails/fileuploadercarrierwave/bin/rails:6: warning: previous definition of APP_PATH w

我正在尝试创建一个rails应用程序,使用carrierwave将文件上传到S3。我按照以下说明操作:。因为本地上传工作正常。但是当涉及到S3时,它抛出了以下错误:

bin/rails:6: warning: already initialized constant APP_PATH
/Users/sancowinx/Code/rails/fileuploadercarrierwave/bin/rails:6: warning: previous definition of APP_PATH was here
在网上搜索后,我发现还有一个名为
fog
的rubygem(根据我上面提到的S3的carrierwave说明,我使用的是
fog aws
)。然后,我尝试改用rubygem
fog
。也会抛出一个错误。但现在它为
未定义的方法
抛出异常:

/Users/sancowinx/Code/rails/fileuploadercarrierwave/config/initializers/carrierwave.rb:2:in `block in <top (required)>': undefined method `fog_provider=' for CarrierWave::Uploader::Base:Class (NoMethodError)
模型

控制器

class S3PostsController < ApplicationController
  def index
    @s3posts = S3Post.all
  end

  def new
    @s3post = S3Post.new
  end

  def create
    @s3post = S3Post.new(s3post_params)

    if @s3post.save
      redirect_to s3_posts_path, notice: "The S3Post #{@s3post.name} has been uploaded."
    else
      render 'new'
    end
  end

  def destroy
    @s3post = S3Post.find(params[:id])
    @s3post.destroy

    redirect_to s3_posts_path, notice: "The S3Post #{@s3post.name} has been deleted."
  end

  private
    def s3post_params
      params.require(:s3_post).permit(:name,:attachment)
    end
end
另外,我将AWS密钥存储在~/.bash_配置文件中,而不是硬编码


我已尝试卸载/重新安装
fog aws
carrierwave
gem,但仍然无法使其工作。有人能帮我找出我做错了什么吗?

问题是,您使用的是当前发布的carrierwave版本,但遵循的是master的文档,两者相隔一年多。您可以通过github()或via阅读0.10.0的自述文件。您需要切换到carrier wave的主版本,或者修改代码以匹配旧的自述文件

fog是一个试图向主要云提供商(AWS、rackspace、google compute等)提供公共接口的gem,但其结果是gem变得相当大,大多数用户实际上只使用了其中的一小部分。几个月前,决定将fog拆分为fog核心,其中包含所有提供商通用的代码,然后是特定于提供商的GEM

fog aws是具有aws特定代码(因此是S3)的gem。fog gem仍然存在,用于向后兼容,但只是拉入所有提取的gem(其中仍有一些尚未提取的提供者)


较新版本的carrier wave中的
fog\u provider
设置允许您控制carrierwave是尝试加载传统的fog gem及其所有提供程序,还是仅加载一个特定的提供程序,如fog aws。

Hartl的Rails教程中有一节(11.4)关于文件存储,我觉得这很有帮助。请确保为S3设置了AWS策略,否则您将得到403。谢谢您的指点。没有注意到专门针对v0.10.0的自述页面。他决定跟着我走。我现在可以运行rails服务器,但必须将rails版本更改为
gem'rails'
,而不是
gem'rails',4.2.1'
。现在我从proc closure中得到了错误
中断。但是rails服务器最终还是可以运行了。我不确定,但是如果你使用的是0.10.0版本的文档,你可能不想把'gem“fog',“~>1.3.1'放到你的gem文件中,因为这个版本看起来很旧,所以只需使用'gem“fog”
class S3Post < ActiveRecord::Base
  mount_uploader :attachment, S3PostUploader
  validates :name, presence: true # validates names
end
  create_table "s3_posts", force: :cascade do |t|
    t.string   "name"
    t.string   "attachment"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
class S3PostsController < ApplicationController
  def index
    @s3posts = S3Post.all
  end

  def new
    @s3post = S3Post.new
  end

  def create
    @s3post = S3Post.new(s3post_params)

    if @s3post.save
      redirect_to s3_posts_path, notice: "The S3Post #{@s3post.name} has been uploaded."
    else
      render 'new'
    end
  end

  def destroy
    @s3post = S3Post.find(params[:id])
    @s3post.destroy

    redirect_to s3_posts_path, notice: "The S3Post #{@s3post.name} has been deleted."
  end

  private
    def s3post_params
      params.require(:s3_post).permit(:name,:attachment)
    end
end
# encoding: utf-8

class S3PostUploader < CarrierWave::Uploader::Base

  storage :fog

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_white_list
    %w(jpg jpeg gif png)
  end

end
CarrierWave.configure do |config|
  config.fog_provider = 'fog-aws'
  config.fog_credentials = {
    :provider               => 'AWS',
    :aws_access_key_id      => ENV['S3_KEY'],
    :aws_secret_access_key  => ENV['S3_SECRET']
  }
  config.fog_directory  = ENV['S3_BUCKET']
end