#はじめる前に:Cloudinaryに登録
様々なファイルを投稿するとき、どうしたらいいのかわからなかったので、画像投稿を参照してPDFを投稿してみました。
このリンクから登録をはじめましょう。
https://cloudinary.com/
右上のsign up for freeを押すと、登録画面に飛びます。
#手順
##Step1 ファイル投稿機能のためにMVCを準備
適当なファイルを使って、作っていきます。
今回は、Topicモデルを使っていきます。
###Topicsテーブルにカラムを追加
今回はファイルだけを投稿するためのアプリケーションなので、pdfカラムをString型で追加します。
(ファイルを保存するときにString型で指定するのはそういうものだと思っちゃいましょう)
今回はTopicsテーブルにstring型のpdfカラムを追加するので、
rails generate migration AddPdfToTopics pdf:string
と打ち込んで実行します。
すると、以下のようなマイグレーションファイルがタイムスタンプ付きで自動生成されます。
class AddPdfToTopics < ActiveRecord::Migration[6.0]
def change
add_column :topics, :pdf, :string
end
end
書き込んだら、ターミナルでmigrateします。ターミナルで以下の操作を行いましょう。
$ rails db:migrate
これで、Topicモデルに、pdfという名前の、string型のカラムが追加できました。
###Viewの作成
まず、index.html.erb
に以下のように追加で記述してください。
<% @topics.each do |t| %>
<!--ここから-->
<a href="<%= image_url t.pdf_url %>" target="_blank">
<div class="post2-2">
<object data="<%= image_url t.pdf_url %>" type="application/pdf"></object>
</div>
</a>
<!--ここまで-->
<%= t.body %>
<%= t.created_at %>
</div>
<% end %>
</div>
実はデータベースにはファイルは保存されておらず、代わりにファイルが置かれる住所が保存されます。なのでt.image_url
のような書き方になります。
次にtopics controller
の一番下に以下のような記述があると思うので、それに「:pdf」の記述を付け加えましょう。
# 割愛
private
def topic_params
params.require(:topic).permit(:body, :pdf)
end
これをしておかないと、pdfのパラメータが取得できず、投稿ができません。
またnew.html.erb
に以下を追加で記述してください。
<%= form_for @topic do |f| %>
<div class="field">
<%= f.label :body %>
<%= f.text_field :body, :size => 140 %>
</div>
<!--ここから-->
<div class="field">
<%= f.label :pdf %>
<%= f.file_field :pdf %>
</div>
<!--ここまで-->
<%= f.submit "投稿" %>
<% end %>
これはファイルを投稿するためのボタンを実装してくれるためのコードです。
file_fieldの場合は、以下の図のようなformが作られます。
ここにユーザーが投稿したいファイルを投稿することになります。
これで下準備は終わりました。次のStepからは実際のファイル投稿機能を実装していこうと思います。
##Step2. ファイル投稿機能
早速ここからファイル投稿機能を導入していこうと思います。
###gemの追加
今回はcloudinary、carrierwave、dotenv-railsというgemを使っていきます。Gemfileの一番下に以下を追加しましょう。
gem 'carrierwave' , '~> 1.3' , '>= 1.3.1'
gem 'cloudinary'
gem 'dotenv-rails'
そしたらターミナルで
$ bundle install
と打ちこんでインストールします。
アップローダーの作成
CarrierWaveのジェネレーターでアップローダーを作成します。以下のコマンドをターミナルに打ち込みましょう。
$ rails g uploader Pdf
uplpder の後ろは、先程追加したカラム名を入れてください。
モデルの修正
Topicモデルを以下のように修正します。
class Topic < ApplicationRecord
# 追記ここから
mount_uploader :pdf, PdfUploader
# 追記ここまで
end
mount_uploader :pdf, PdfUploader
はファイルを指定の場所に保存することを表します。
次に保存場所を指定するアップローダの設定です。
app/uploaders/pdf_uploader.rbの6~8行目を変更しましょう。
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
上記を下図のように変えます。
# Choose what kind of storage to use for this uploader:
if Rails.env.production?
include Cloudinary::CarrierWave
CarrierWave.configure do |config|
config.cache_storage = :file
end
else
storage :file
end
# storage :fog
cloudinaryは外部のストレージサービスです。本番環境(リリース後=production)ではcloudinaryにファイルが保存され、それ以外(開発環境=ローカル)では自分のpcに保存されます。(publicフォルダー内に保存されます)
###APIキーの非公開
Cloudinaryの各アカウントには「Cloud name」、「API Key」、「API Secret」というアカウント固有の秘密のIDのようなものが付与されています。
この情報は非常に機密性が高く決して外部に漏らしてはいけない情報なので、これらの値が間違って公開されないような処理を施す必要があります。
のでこの節ではWebサービスを公開した時にそれらの値を公開しないようなコードを書いていくことにします。
三つの値は以下から確認することができます。
Cloudinaryマイページ
.env
というファイルを**アプリケーションディレクトリ(appやdbやGemfileがあるディレクトリ)**に自分で作成します。
以下の図のようになっていればオッケーです。
※vendorフォルダーの中ではないので注意してください。
次に作成した.env
ファイルに以下を入力します。
CLOUD_NAME=q0w9e8r7t6yu5 #←この値は人によって違います!!
CLOUDINARY_API_KEY=123456789012345 #←この値は人によって違います!!
CLOUDINARY_API_SECRET=1a2s3d4f5g6h7j8k9l0a1s2d4f5g6h1q #←この値は人によって違います!!
ここで「=」の後のそれぞれの値は先ほどのCloudinaryのマイページで取得したキーに書き換えておいてください(自分が取得したキーは絶対他言しないように!!また数字は個々人によって変わります)。
また、書き換える際は、コメントアウト部分を削除してください!
最後に隠しておきたいデータを定義した.envファイルをみんなに公開してしまっては意味が無いのでこのファイルは公開しないようにします。アプリケーションディレクトリにある.gitignore
に下記を追加します。
※もし.gitignore
ファイルがない場合はアプリケーションディレクトリーにて作りましょう!
# 省略
/.env
これでOKです!
###APIキーの利用
最後の手順です!
まずはconfigフォルダにcloudinary.yml
ファイルを作成してください。
config/cloudinary.ymlに以下のようにそのままコピペしてください。
development:
cloud_name: <%= ENV['CLOUD_NAME'] %>
api_key: <%= ENV['CLOUDINARY_API_KEY'] %>
api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %>
enhance_image_tag: true
static_file_support: false
production:
cloud_name: <%= ENV['CLOUD_NAME'] %>
api_key: <%= ENV['CLOUDINARY_API_KEY'] %>
api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %>
enhance_image_tag: true
static_file_support: false
test:
cloud_name: <%= ENV['CLOUD_NAME'] %>
api_key: <%= ENV['CLOUDINARY_API_KEY'] %>
api_secret: <%= ENV['CLOUDINARY_API_SECRET'] %>
enhance_image_tag: true
static_file_support: false
これでAPIキーを非公開にしたまま利用することができました。
#PDFのダウンロード
PDFをダウンロードするときは、表示されているファイルを右クリックして、保存することができます!
#ファイル内のPDFを表示させる
app/assets/images
内に、PDFファイルを入れます。
その後、表示したいページのviewに、下の文章を入れます!
<object data="../../../assets/07.pdf" type="application/pdf" width="100%" height="100%"></object>