Ruby中にGCSでのデータの操作

# はじめに
この記事はLinkbal_Advent_Calendar_2020の20日目の記事です。
今日はRubyでGCS(Google Cloud Storage)でのデータのいくつかの操作を簡単に紹介していただきます。
# 実装

### Gem設定
まずは`google-cloud-storage`の`gem`をinstallしなければならないです。最低限必要なルビーバージョンは`2.4`であることを忘れないでくださいね。
**方法1：**
`Gemfile`のファイルに以下の行を追加したら、`bundle install`を実行する。

```ruby
gem 'google-cloud-storage', '~> 1.29', '>= 1.29.2'
```

**方法2：**
直接コマンドで実行することができます。

```text
$ gem install google-cloud-storage
```
### 認証
使用する前に、認証手順が必要です。認証情報は`project_id`と`credentials`を含みます。

```ruby
require "google/cloud/storage"

storage = Google::Cloud::Storage.new(
  project_id: "my-project",
  credentials: "/path/to/keyfile.json"
)
```
- `project_id`はプロジェクトのIDです。
- `credentials`は認証情報を格納するJSONファイルへのパスです。<br>
普通は`API Manager`を選んで、`Credentials`をクリックします。その後、`Add credentials`の選択ボックスを見つけて、`Service account`を選びます。作成したら、新しい`Json`キーファイルをダウンロードします。どこかに保存して、パスを認証情報の部分に記入します。<br>
以外に、GCP(Google Cloud Platform)でcredentialsのパスを取り方:
`IAM&Admin => Service Accounts`で新しい`Service Account`を作り、新しい`Keys`を作成してから、`Json`の形でダウンロードします。その`Keys`はバケットにアクセスするのに使います。ダウンロードしたら、どこかで置いて、そのファイルへのパスを記入します。

認証に関するのを詳しく知りたい方は以下のリンクに参考できます。
https://googleapis.dev/ruby/google-cloud-storage/latest/file.AUTHENTICATION.html
### データ操作
##### バケット
バケットは、データのコンテナです。プロジェクトで作成できるバケットの数に制限はありません。 バケットを使用して、データへのアクセスを整理および制御できます。

指定バケットに取得する時には、`storage.bucket "bucket_name"`のステートメントを使います。
例：

```ruby
require "google/cloud/storage"

storage = Google::Cloud::Storage.new

bucket = storage.bucket "my_bucket"
```
プロジェクト中には全てバケットを取りたい祭に

```ruby
buckets = storage.buckets
```
API呼び出しの数を制限したい時に

```ruby
buckets = storage.buckets
buckets.all(request_limit: 10) do |bucket|
  # do something
end
```

以外に、新しいバケットを作るために、`storage.create_bucket "bucket_name"`を使います。
例：

```ruby
bucket = storage.create_bucket "my_new_bucket"
```

##### ファイル
ファイルは、Google CloudStorageに保存する個々のデータオブジェクトです。
バケットでの指定ファイルに取得する時にはファイル名が要ります。

```ruby
require "google/cloud/storage"

storage = Google::Cloud::Storage.new

bucket = storage.bucket "my_bucket"
file = bucket.file "avatars/image1.png"
```
バケットでの全てファイルを取りたい祭に

```ruby
all_files = bucket.files
```
または、指定したパスにあるすべてのファイルを取得できます。

```ruby
all_files = bucket.files prefix: "avatars/"
```
他に、バケットに新しいファイルを作成する際にローカルで保存しているファイルへのパスを指定しなければなりません。

```ruby
require "google/cloud/storage"

storage = Google::Cloud::Storage.new

bucket = storage.bucket "my_bucket"
bucket.create_file "/tmp/images/avatars/image1.png",
                   "avatars/image1.png"
```
##### ダウンロードファイル
ファイルをダウンロードしたい時に`file.download`を使用します。

```ruby
require "google/cloud/storage"

storage = Google::Cloud::Storage.new

bucket = storage.bucket "my_bucket"
file = bucket.file "avatars/image1.png"
file.download "/tmp/images/avatars/image1.png" # path to save file at local
```
また、StringIOオブジェクトにダウンロードすることもできます。

```ruby
require "google/cloud/storage"

storage = Google::Cloud::Storage.new

bucket = storage.bucket "my_bucket"
file = bucket.file "hello_world.txt"

downloaded = file.download
downloaded.rewind
downloaded.read # => "Hello World!"
```
クライアントで認証されていないで公開ファイルをダウンロードしたい際に、`skip_lookup: true`を使ってください。

```ruby
require "google/cloud/storage"

storage = Google::Cloud::Storage.new

bucket = storage.bucket "public_bucket", skip_lookup: true
file = bucket.file "path/to/public_file.ext", skip_lookup: true

downloaded = file.download
```
##### アクセス制御

```ruby
require "google/cloud/storage"

storage = Google::Cloud::Storage.new

bucket = storage.bucket "my_bucket"
file = bucket.file "avatars/image1.png"

email = "test@example.co.jp"
```
バケットやファイルへのアクセスはユーザーに許可や限定できます。

```ruby
bucket.acl.add_reader "user-#{email}"
file.acl.add_reader "user-#{email}"
```
同じに、バケットやファイルへのアクセスはユーザーに許可や限定できます。

```ruby
bucket.acl.add_reader "group-#{email}"
file.acl.add_reader "group-#{email}"
```
また、バケットやファイルへのアクセスは事前定義された権限のリストに付与することもできます。

```ruby
bucket.acl.public!
file.acl.public!
```
# 終わりに
以上です。上記には何か間違った点があればコメントでご意見頂けると幸いです。記事を閲覧いただき誠にありがとうございます。:smile:
また次の記事に。
# 参考
https://github.com/googleapis/google-cloud-ruby/tree/master/google-cloud-storage