質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.21%

S3に画像保存がしたい ArgumentErrorが出ます

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 3
  • VIEW 881

ma_k

score 14

ruby on rais でアプリを開発しています。
OSはMacです。
プロフィール画像を保存するのに、
S3に保存できるように設定しようとしていますが、
ArgumentError in UsersController#update
is not a recognized provider

イメージ説明

が出ます。
原因を検索してもわからず、
困っています。

参考サイト1
参考サイト2

を見ながら進めました。

notebook/app/uploaders

class AvatarUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick

  # S3にアップロードする場合
  if Rails.env.production? || Rails.env.staging?
    storage :fog
  else
    storage :fog
  end

  # S3のディレクトリ名
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # デフォルト画像は700x700に収まるようリサイズ
  process :resize_to_limit => [700, 700]

  # サムネイル画像
  version :thumb do
     process resize_to_fill: [100, 100]
  end

  # 許可する画像の拡張子
  def extension_whitelist
     %w(jpg jpeg gif png)
  end

  # 保存するファイルの命名規則
  def filename
     "something.jpg" if original_filename
  end

  protected
  # 一意となるトークンを作成
  def secure_token
     var = :"@#{mounted_as}_secure_token"
     model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
  end
end
notebook/config/initializers

CarrierWave.configure do |config|
  config.fog_credentials = {
    provider: 'AWS',
    aws_access_key_id: ENV['####キー入れました####'],
    aws_secret_access_key: ENV['####キー入れました####'],
    region: ENV['us-east-2'],
    path_style: true
  }
  config.fog_public = true
  config.fog_attributes = {'Cache-Control' => 'public, max-age=86400'}

  config.remove_previously_stored_files_after_update = false

  config.fog_directory = ENV['AWS_S3_BUCKET']
  config.asset_host = ENV['AWS_S3_URL']
end
# 日本語の文字化けを防ぐ
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
notebook/app/controllers/users

class UsersController < ApplicationController


  def update
     @user = User.find(params[:id])
     @user.update(params.require(:user).permit(:name, :profile,:avatar,:email))
     redirect_to("/users/#{@user.id}")
  end


end
notebook/app/views/users

               <div class="form-body">
                  <% @user.errors.full_messages.each do |message| %>
                   <div class="form-error">
                    <%= message %>
                  </div>
                  <% end %>
                 <%= form_for @user do |f| %>
                 <p >名前</p>
                 <%= f.text_field :name, :class => "form-control my-form" %>
                 <p>メール</p>
               <%= f.text_field :email, :class => "form-control my-form" %>
               <div class="circle-avatar">

              <% if current_user.persisted? && current_user.avatar? %>
             <%= image_tag current_user.avatar.to_s, class: 'avatar_present_img' %>

       <label>
                 <%= f.check_box :remove_avatar %> 画像を削除</label>
                            <% else %>
                            <%= image_tag 'a-logo.gif', class: 'avatar_present_img' %>
                            <!-- classを追加 -->
                            <%= f.hidden_field :avatar_cache %>
                            <% end %>
                            <%= f.file_field :avatar, id: 'post_img' %>
                            <!-- idを追加 -->
                        </div>
                        <p>プロフィール</p>
                        <!-- name属性を設定してください -->
                        <%= f.text_area :profile, :class => "commentForm_textarea" %>
                        <input type="submit" value="保存">
                        <!-- endを追加してください -->
                        <% end %>
                    </div>


アクセスキーなども入力したのですが、
うまくいきません

アプリ開発初めてなので、
回答がすぐ理解できるか自信がありません。
申し訳ございませんが、
よろしくお願いいたします。

どなたかご教授いただけたらと思います。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • siruku6

    2019/09/25 22:43

    https://stackoverflow.com/questions/16114957/carrierwave-fog-s3-is-not-a-recognized-storage-provider

    こんな記事もあったので確認なのですが、2つ目のファイル名が書いていないファイルのフルパスと、アプリケーションのルートディレクトリのフルパスを掲載していただいても構いませんか?

    キャンセル

  • ma_k

    2019/09/26 12:14

    コメントありがとうございます。
    2つ目のファイル修正しました。
    恐れ入ります。アプリケーションのルートディレクトリのフルパスはどうやって掲載したらいいのでしょうか。。。

    キャンセル

  • siruku6

    2019/09/26 22:00

    /home/ユーザー名/abcde/config/initializers/....
    のように記載すると皆さんに伝わると思います

    使用OSがwindowsだった場合、この書き方にはちょっと戸惑うかもしれませんが

    キャンセル

  • ma_k

    2019/09/27 00:55

    なるほど。わかりました。修正します!

    キャンセル

回答 3

0

こんばんは。
AWS側の設定は正しくできているかと思いますが、AWSのアクセスキーやシークレットを使って、プログラムから操作をすること自体は、初めてでしょうか?

CarrierWaveの設定が気になりましたので、どちらかというと質問になりますが、切り分けのためご確認いただければと思います。

CarrierWaveでの環境変数の設定

一見すると、aws_access_key_id: ENV['####キー入れました####'] という一行を始め、regionの指定のところまで、誤りなのでは?と思います。

  config.fog_credentials = {
    provider: 'AWS',
    #ここが間違い?
    aws_access_key_id: ENV['####キー入れました####'],
    #ここも間違い?
    aws_secret_access_key: ENV['####キー入れました####'],
    #ここも間違い?
    region: ENV['us-east-2'],
    path_style: true
  }

本来は、デフォルトでそれぞれ aws_access_key_idはAWS_ACCESS_KEY_ID, aws_secret_access_keyはAWS_SECRET_ACCESS_KEYという名前の環境変数に、値が設定されます。

ruby側でこの値を呼び出す際には、本来はこのような指定になります。

  config.fog_credentials = {
    provider: 'AWS',
    aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
    aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
    region: 'us-east-2',
    path_style: true
  }

もしGitHubのようなSaaSのリポジトリを使ってソースコードを管理しているなら、AWSのアクセスキーのような秘匿情報はソースコード中にハードコードすると漏洩する危険性がありますので、このように環境変数からするように書きます。

ENV['####キー入れました####']

これだと、もし本当に ENV['AKxxxxxxxxxxxxxxxxM7'] みたいな値をセットしてしまったとしたら、誤りですし、うまく動かなかったにしても、キーのハードコードに近いので、ご注意ください。

ソースは手元の環境のみで動かしていて、キーはコミットしていないという状態なら、

  config.fog_credentials = {
    provider: 'AWS',
    aws_access_key_id: 'ここに実際のアクセスキーIDの値',
    aws_secret_access_key: 'ここに実際のシークレットアクセスキーの値',
    region: 'us-east-2',
    path_style: true
  }

でうまく動くか試せば良いかとは思います。
(ただ、やはりリモートリポジトリにキーを直書きしたままプッシュしないようにご注意を)

OSの情報やプログラムをコーディング、動かしている環境

もし、キーをハードコードした状態でうまく動いたなら、あとはハードコードの部分を環境変数で渡すように修正すれば良いです。

なお、環境変数の設定はOSによって差があったりしますので、後付けで申し訳ないのですが、実行環境(OS)だけは少なくとも質問に追記いただけると助かります。

あとから同じように困って、この質問にたどりついた方にとっても、助かりますので。

以上ですが、見当違いだったらご容赦ください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/30 18:22

    早速、コメント通りに実行してみました。
    編集ページを表示することはできました!
    そのあと保存しようと試みたら、
    Broken pipe (Errno::EPIPE)というみたことがないエラーに
    なりました。
    今解決策を調べている所です。
    一歩進めました。ありがとうございます。

    キャンセル

  • 2019/09/30 21:21

    regionのところは、'ap-northeast-1' (アジアパシフィック (東京))ではないですか?
    'us-east-2' (米国東部 (オハイオ)) と書かれていますが、念の為。バケット名も確認するといいかもしれませんね。

    キャンセル

  • 2019/11/25 16:22

    長々と返事してなくて申し訳ありません。エラーの解決試みておりましたが、
    頭の容量が足らずフリーズしておりました。
    質問のエラーを含め、検討している機能は
    もう少しスキルつけてから再チャレンジしようと思います。
    お世話になりました。またご縁ありましたらよろしくお願いします。

    キャンセル

0

すみません、普段私が使っている設定なのですが、もしなかなかうまくいかないようであれば、こんな設定も試してみてください

# config/initializers/carrierWave.rb

require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

CarrierWave.configure do |config|
  config.storage :fog
  config.fog_provider = 'fog/aws'
  config.fog_directory  = 'バケット名'
  config.asset_host = 'https://s3.amazonaws.com/バケット名'
  config.fog_public = false
  config.fog_credentials = {
    provider: 'AWS',
    aws_access_key_id: 'AWS_ACCESS_KEY_ID',
    aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY',
    region: 'us-east-2' # ←自身のregionを入力
  }
end


↑のは最低限の情報で、一部省略してますが、これでも動くはずです。

↓実際使っているのはここに書いてあります
[Rails4] CarrierWave 経由で AWS S3 に pdf をアップロード(ACCESS DENIED の対処)

補足

また、エラーを見る限りでは環境変数自体が読み込めておらず空になっているように見えますので、環境変数が設定されているか、環境変数名が間違っていないかなども確認した方が良いでしょう。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/30 17:36

    コメントありがとうございます。
    いただいたコメントの中のコードに書き換えて試してみましたが、
    同じエラーでした。
    補足に追記してくださった環境変数について無知だったため、
    検索し、試している所です。
    環境変数を調べながら
    https://qiita.com/yuichir43705457/items/7cfcae6546876086b849
    を参考に試していた所、エラーが代わり、
    Missing required arguments: aws_access_key_id, aws_secret_access_key
    になりました。引き続き原因と解決を探しています!

    キャンセル

  • 2019/10/01 20:51

    なぜそのエラーが出るのかイメージが沸かないのですが、そのエラーであればこの人が解決しているようです
    https://qiita.com/y_u_y_a/items/72bd74ab1a2d2950435a

    そのエラーが出た該当箇所(ファイル名と行番号)は判明していますか?

    キャンセル

  • 2019/11/25 16:21

    長々と返事してなくて申し訳ありません。エラーの解決試みておりましたが、
    頭の容量が足らずフリーズしておりました。
    質問のエラーを含め、検討している機能は
    もう少しスキルつけてから再チャレンジしようと思います。
    お世話になりました。またご縁ありましたらよろしくお願いします。

    キャンセル

check解決した方法

-1

もう少し寝かせて再チャレンジ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる