概要
みなさんこんにちはcandleです。今回はs3にあるフォルダを丸ごとrailsのaws-sdk gemを使用して削除してみたいと思います。
実はこの方法を確立するまですごく四苦八苦しました。なんとかstackoverflowの記事を参考にしてできました。長い記事に成るかもしれませんがよろしくお願いします。
記事中で開発している場所は家のローカル環境のrailsです。必ずしもs3を使うからと言って、EC2上で作業する必要はありません。
前提
railsの環境が構築されている
awsのアカウントを持っていて割と自由に使える
今回もtwitterbootstrap gemとscaffoldを使って説明します。別段、bootstrap gemが入っている必要がありませんが、見栄えが多少異なります。
rails4のtwitterbootstrap gem でscaffoldを作る方法は下のURLにあるので、もし、同じように進行したい場合は下の記事を参考にしてください。
ruby on rails4でtwitterbootstrap3のgemを使用してscaffoldを作成する
aws-gemを用意する
適当なプロジェクトを作成して、そのGemfileに下の内容を書き込みましょう。
私はbootstrap3というプロジェクトを使います。
gem 'aws-sdk'
gemをインストールする為に下のコマンドを入力しましょう。
bundle install
aws-sdk gemの準備が完了しました。
s3folderというscaffoldを作る
scaffoldを使って説明していきたいと思います。
scaffoldの詳しいことは別の記事に書いてあるので、ここではコマンドだけを紹介します。
下のコマンドでs3folderというscaffoldを作成します。
rails g scaffold S3folder title:string folder_name:string comment:string
作成されたマイグレーションファイルをデータベースに反映させます。
bundle exec rake db:migrate
scaffoldが完成しました。
twitterbootstrapのテーマを反映させる
もしも、twitterbootstrap gemが入っているなら下のコマンドでテーマを反映させます。
rails generate bootstrap:install static rails g bootstrap:layout application rails g bootstrap:themed S3folders
s3にファイルを削除するためのバケットを作る
railsのセットアップも終わったのでs3にバケットを用意しましょう。
awsのs3のサイトに飛んで、
s3のサービスから「s3contents」というバケットをつくります。
ちなみに後から知ったのですが、同じ名前は取れないので、別の名前にするかリージョンを変えるかしてみてください。
作成できました。
s3contentsのバケットを選択してその中にimagesというフォルダを作ります。
これでs3の準備はできました。
s3へアクセスるためのaccess_keyとsecret_keyを取得する
これはjoppotの別の記事にまとめてあるのでそちらを参照してください。
awsのs3を操作する為のaccess keyとsecret keyを取得する(IAM)
ファイルをアップロードしておく
予め、a.pngとb.pngをアップロードしておきます。別に、フォルダ丸ごと削除するので、ファイルを用意する必要は無いのですが、気分的にファイルをimagesフォルダに入れておきます。
これで、ファイルのアップロードが完了しました。
テーブルを用意する
先ほどのimagesフォルダに紐づくテーブルを用意しておきます。
folder_nameカラムにはs3のフォルダのURLをおさめます。
フォルダのURLは人によって違うので適宜、自分のURLに編集してください。
私の場合は「http://s3-ap-northeast-1.amazonaws.com/s3contents/images/」がimagesフォルダのURLになります。
そしたら、そのURLを元に、下のSQL文を作ります。
INSERT INTO "s3folders" VALUES(1,'firstfolder','フォルダのURL','good folder','2014-06-14 04:49:58.585749','2014-06-14 04:49:58.585749');
例えば、自分の場合は下の用になります。
INSERT INTO "s3folders" VALUES(1,'firstfolder','http://s3-ap-northeast-1.amazonaws.com/s3contents/images/','good folder','2014-06-14 04:49:58.585749','2014-06-14 04:49:58.585749');
ここで重要なのが、URLの最後なのですが、からならずスラッシュまで入れておいてください。
スラッシュを入れる事でフォルダと認識されます。
railsのコーンソールで上のsql文を実行してレコードを作ります。
dbに入って
bundle exec rails db
上のsql文を実行すれば、
レコードが作成されました。
s3imagesコントローラーを編集する
awsの設定コードを記述する
app/controllers/s3folders_controller.rbを開いて、
クラスの中に上部に下のセッティングソースを書きます
AWS.config(access_key_id: 'あなたのアクセスキー', secret_access_key: 'あなたのシークレットー', region: 'ap-northeast-1')
ここで、別記事で紹介しているIAMで入手した、アクセスキーとシークレットキーを入力しましょう。
したのような感じになると思います。
regionを見ると、「ap-northeast-1」にしています。これはs3をどこに置いているかをさしています。それぞれ、確認してそれを適切に設定してください。
ちなみに、確認の仕方は、s3のサイトに言った時にURLに表示されます
destroyアクションを編集する
scaffoldで作成したdestroyアクションは下のようになっています。
def destroy @s3folder.destroy respond_to do |format| format.html { redirect_to s3folders_url } format.json { head :no_content } end end
下のようにします。
def destroy #s3contentsの所は自分の作成したバケット名 s3folderpath=@s3folder.folder_name.gsub("http://s3-ap-northeast-1.amazonaws.com/s3contents/","") s3 = AWS::S3.new #s3contentsの所は自分の作成したバケット名 s3.buckets['s3contents'].objects.with_prefix(s3folderpath).delete_all @s3folder.destroy respond_to do |format| format.html { redirect_to s3folders_url } format.json { head :no_content } end end
1番始目の行はs3のバケットから見たフォルダのパスにソートしています。
例えば、カラムfolder_nameに「http://s3-ap-northeast-1.amazonaws.com/s3contents/images/」が入っている場合、「images/」にソートされます。
その後、s3というインスタンスを作り、objects.withprefixでフォルダのパスを投げて、delete_allでフォルダを丸ごと消します。
これでフォルダが削除できるようになりました。
実際にフォルダを削除してみる
サーバを起動して
bundle exec rails s
下のURLに移動して
http://localhost:3000/s3folders
imagesフォルダを削除したいと思います。
「delete」ボタンを押すと、
レコードが削除されて、
s3のフォルダも削除されています。
まとめ
ここでもう一度まとめますが、必ず、フォルダを指定する時はスラッシュまで入れてください。そこまでがフォルダを表します。上の例で言えば、images/までがフォルダを表していて、imagesだけではフォルダは削除されません。
私はこの部分で躓いて時間がかかりました。みなさんもここさえ気をつければ大丈夫です。