---
# System prepended metadata

title: Google Storage + Shrine

---

# Google Storage + Shrine

## Google網站設定

1. 到 [https://console.cloud.google.com](https://console.cloud.google.com/home/dashboard?authuser=1&hl=zh-TW&project=igdemoproject) 申請帳號
2. 建立新專案
3. 建立新 storage 
    1. 權限：統一
    2. 成員：增加 allUsers ⇒ storage object viewer
4. I AM與管理
    1. 增加成員 = 擁有者
    2. 下載帳號 json

## 專案設定

1. 建立model 

    ```ruby
    rails g scaffold Post content:text image_data:text
    ```

    controller 使用範例

    ```ruby
    def post_params
    	params.require(:post).permit(:content, :image)
    end
    ```

    view 使用範例

    ```ruby
    <div class="field">
    	  <%= form.label :image %>
        <%= form.file_field :image %>
    </div>

    <%= image_tag post.image_url, width: "200" %>
    ```

2. gemfile 加入 shrine 或其他圖片上傳器

    ```ruby
    gem 'shrine'
    ```

3. 加入 config/initializers/shrine.rb

    ```ruby
    require "shrine"
    require "shrine/storage/file_system"

    Shrine.storages = {
      cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"), # temporary
      store: Shrine::Storage::FileSystem.new("public", prefix: "uploads"),       # permanent
    }

    Shrine.plugin :activerecord           # loads Active Record integration
    Shrine.plugin :cached_attachment_data # enables retaining cached file across form redisplays
    Shrine.plugin :restore_cached_data    # extracts metadata for assigned cached files
    ```

4. 在 model 引入圖片上傳器

    ```ruby
    class Post < ApplicationRecord
      include Shrine::Attachment(:image)
    end
    ```

5. add google gem

    ```ruby
    gem 'google-cloud-storage'
    gem 'shrine-google_cloud_storage'
    ```

6. 在 shrine.rb 加入google storage 設定
    1. project_id 是 專案 id
    2. bucket 是 google storage id
    3. gcp.json 是在新增成員時下載的 json

    ```ruby
    require "shrine"
    require "shrine/storage/file_system"
    require "shrine/storage/google_cloud_storage"

    if Rails.env.production?
    	Google::Cloud::Storage.configure do |config|
    	  config.project_id  = "igdemoproject"
    	  config.credentials = "config/keys/gcp.json"
    	end

      Shrine.storages = {
        cache: Shrine::Storage::GoogleCloudStorage.new(bucket: "ig_demo_storage_0814"),
        store: Shrine::Storage::GoogleCloudStorage.new(bucket: "ig_demo_storage_0814"),
      }
    else
      Shrine.storages = {
        cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"), # temporary
        store: Shrine::Storage::FileSystem.new("public", prefix: "uploads"),       # permanent
      }
    end

    Shrine.plugin :activerecord           # loads Active Record integration
    Shrine.plugin :cached_attachment_data # enables retaining cached file across form redisplays
    Shrine.plugin :restore_cached_data    # extracts metadata for assigned cached files
    ```