Ruby on RailsからGoogle Driveにファイルをアップロードしてみた(表示&削除も)
はじめに
先日、Railsで作成した業務管理系ツールにて、「フォームからファイルをアップロードするとGoogleDriveの指定したディレクトリ内に格納される」という機能を実装しました。GoogleDriveAPIは初見だったのですが、公式のリファレンスをはじめ英語の情報ばかりで困ったのと割と古めの情報が多かったので実装した内容を記事として残します。
今回説明しないこと
- Google Drive APIの有効化、認証方法
- こちらはRuby用の公式リファレンスやRuby on Rails等のアプリ用の公式リファレンスなどを参照
準備
- Railsから使用するアップロード用のモデルImageと対応するimagesコントローラーを作成
- カラムは
file
のみ
- カラムは
- ビューはslimで記載しているため必要に応じて読み替える
- 今回使用する全ての機能で必要となるGoogle Drive APIを使うための設定(API有効化と認証方法)を
application_contoller.rb
に記載し適宜呼び出して使用する
class ApplicationController < ActionController::Base
def google_drive_initialize
require 'google/apis/drive_v3'
require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'fileutils'
credentials_dir = '.credentials'
@CLIENT_SECRETS_PATH = File.join(credentials_dir, 'client_secret.json')
@CREDENTIALS_PATH = File.join(credentials_dir, 'credentials.yaml')
@OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
@APPLICATION_NAME = 'app_name'
@SCOPE = Google::Apis::DriveV3::AUTH_DRIVE
@@drive = Google::Apis::DriveV3
@@service = @@drive::DriveService.new
@@service.client_options.application_name = @APPLICATION_NAME
@@service.authorization = google_drive_authorize
end
end
アップロード機能の実装方法
①Google Drive上に保存したいフォルダを作成してフォルダのIDを取得
- GoogleDriveを開いてマイドライブ内にファイルを保存したいフォルダを作成する
- 作成したフォルダに移動する
- URLを確認し「https://drive.google.com/drive/folders/xxxxxx/」 のxxxxxxの部分が保存するフォルダのIDとなるのでコピーする
②取得したIDを使ってアップロード機能を作成
= form_for @image, :url=>{:controller=>"images", :action=>"google_drive_upload"} do |f|
= f.file_field :file
= f.submit "アップロード"
def form
@image = Image.new
end
def google_drive_upload
# application_contoller.rbに記載した情報を読み込み
google_drive_initialize
# ①で取得したIDを変数に格納
folderId = 'xxxxxx'
# フォームから受け取ったファイルを一度railsアプリ内の「public/uploads/images/'」というフォルダに格納する
uploadFile = images_params[:file]
fileName = uploadFile.original_filename
dirPath = 'public/uploads/images'
filePath = dirPath + fileName
Dir.chdir Rails.root
outputPath = Rails.root.join(dirPath, fileName)
File.open(outputPath, 'w+b') do |fp|
fp.write uploadFile.read
end
# ファイルの名前やアップするフォルダの情報を記述
file_metadata = {
name: fileName,
parents: [folderId]
}
# アップロード
@@service.create_file(
file_metadata,
fields: 'id',
upload_source: filePath,
)
redirect_to images_form_path
end
private
def images_params
params.require(:image).permit(:file)
end
アップロード済みのファイルを表示する機能の実装方法
①取得したいファイル(フォルダ)があるフォルダのIDを取得
-
取得したいファイルがあるフォルダのURLを確認し「https://drive.google.com/drive/folders/xxxxxx/」 のxxxxxxの部分が保存するフォルダのIDとなるのでコピーする
②取得したIDを使ってファイル表示機能を作成
images_controller.rbdef google_drive_file_index # application_contoller.rbに記載した情報を読み込み google_drive_initialize # ①で取得したIDを変数に格納 folderId = 'xxxxxx' # 取得したIDをもとにGoogle Driveのフォルダにアクセスしフォルダ内の全ファイルを取得する @response = @@service.fetch_all(items: :files) do |page_token| @@service.list_files( q: "'#{folderId}' in parents and trashed = false", spaces: 'drive', fields: 'nextPageToken, files(id, name)', page_token: page_token ) end end
google_drive_file_index.html.slim- @response.each_with_index do |file,i| = file.id = file.name = link_to 'ファイルへのリンク', 'https://drive.google.com/file/d/' + file.id + '/view' img src="http://drive.google.com/uc?export=view&id=#{file.id}" - if i == 0 p ファイルが存在しません - else p = "#{i + 1}個のファイルがあります"
eachでフォルダ内のファイルデータを一つずつ取り出す
@responseはファイルが存在しなくとも設定データ等を情報として持っているので
if @response.present?
といった方法で存在確認をするのではなくeach_with_index
でループ回数を取得してファイルの存在確認を行うfile.id
やfile.name
でファイルが持っている情報を取り出せるaタグのhrefに指定のURLを記載し、該当部分にファイルのIDを埋め込むことでファイルへのリンクを作成できる
imgタグのsrcにファイルのIDを埋め込むことでWebサイトに直接Google Drive内のファイルを表示させることができるが、Google Drive内のファイルアクセス権限が外部に開かれていない場合はエラーになる
アップロード済みのファイルを削除する機能の実装方法
①削除したいファイル(フォルダ)があるフォルダのIDを取得
-
削除したいファイルがあるフォルダのURLを確認し「https://drive.google.com/drive/folders/xxxxxx/」 のxxxxxxの部分が保存するフォルダのIDとなるのでコピーする
②取得したIDを使ってファイル削除機能を作成
images_controller.rbdef google_drive_file_delete(fileId) # application_contoller.rbに記載した情報を読み込み google_drive_initialize @@service.delete_file(fileId) redirect_to images_google_drive_file_index_path end def google_drive_file_index # application_contoller.rbに記載した情報を読み込み google_drive_initialize # ①で取得したIDを変数に格納 folderId = 'xxxxxx' # 記事内、一つ前の手順で確認したファイルを表示する機能でIDを取得する @response = @@service.fetch_all(items: :files) do |page_token| @@service.list_files( q: "'#{folderId}' in parents and trashed = false", spaces: 'drive', fields: 'nextPageToken, files(id, name)', page_token: page_token ) end end
google_drive_file_index.html.slim- @response.each_with_index do |file,i| = file.name = link_to '削除', images_google_drive_file_delete_path(file.id)
ループ内で取り出したファイルのIDを
/images/google_drive_file_delete/
にパラメーターとして送る
Author And Source
この問題について(Ruby on RailsからGoogle Driveにファイルをアップロードしてみた(表示&削除も)), 我々は、より多くの情報をここで見つけました https://qiita.com/ku_ma/items/161f483a103e955144b2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .