RailsアプリでCarrierWaveからActiveStorageへの移行

NJピアマン
NJピアマン

フォローしている

Jun20,2018·9分読み取り

EPFL Extension SchoolではRuby on Railsを使用してwebアプリケーション開発を教えています。 これは、固体であり、試してみました-と-信頼され、web開発について学ぶあなたの最初のステップを取るときに簡単に従う構造を提示する素晴らしいフ

しかし、それはまた、毎年改善と新機能がリリースされて、ソフトウェアの絶えず進化している作品です。 バージョン5.2のRailsへの最近の追加の一つは、ActiveStorage機能であり、コアRailsフレームワークに簡単なファイルアップロード管理を初めて追加します。

webアプリケーション開発プログラムの最初の反復では、Railsアプリケーションにファイルアップロードを追加する方法を学ぶ主題が含まれています。 しかし、プログラムではRails5.1を使用していますが、ファイルアップロードの件名は、CarrierWaveと呼ばれるファイルアップロードを追加するために広く使用されて これは、railsアプリでファイルアップロードを実装することを可能にする堅実なサードパーティの宝石であり、学習者プラットフォームを含む多くの実世界のRuby on Railsアプリで使用されています。

しかし、ActiveStorageの導入により、これらのサードパーティの宝石は、Rails内にバンドルされたこの新しいソリューションよりも魅力的ではありません。 実際、他の人気のあるサードパーティ製のファイルアップロード宝石の一つであるPaperclipは、ActiveStorageを支持して廃止されたことをすでに発表しています。 Paperclipの開発者は、ActiveStorageが開発者にとってより良い選択であることを認識し、独自のgemのさらなる作業を停止しました。それでは、Rails5.1のCarrierWaveからRails5.2のActiveStorageに移行するために必要なものを具体的に見てみましょう。

アプリケーション

webアプリケーション開発プログラムでは、My Bucket Listというwebアプリケーションを構築しています。 これは、ユーザーが常に達成したいと思っていた経験を作成し、追跡することを可能にするアプリです。 ユーザーは、他の人が作成したものを見て、あまりにもそれらを追跡することができます。 アプリの機能の一つは、ユーザーが自分のアバターをアップロードすることができ、我々はCarrierWaveを使用してファイルのアップロードや添付ファイルについて学ぶた

ユーザーは、CarrierWave

を使用して、このフォームでアバターをアップロードすることができますので、最初に、CarrierWaveを使用して簡単な添付ファイルを追加することに関す

CarrierWave設定

プロジェクトにCarrierWaveを含めるには、次のようにする必要があります:

  • CarrierWave gemをGemfileに追加します。
  • は、設定初期化子config/initializers/carrierwave.rb内にActiveRecord用のCarrierWaveアダプタを含めます。

そして、モデルに画像添付ファイルを追加するには、次のようにする必要があります:

  • rails generate uploader UploaderNameを使用してアップローダーを生成します。
  • モデルに属性を追加して、各レコードの添付ファイル名を保存し、関連するデータベース移行を行います。
  • アップロードの保存場所やデフォルトの画像など、アップロード者の値を編集します。
  • 特定のアップローダーを含めるには、モデル内のmount_uploaderマクロを使用します。
  • 画像をアップロードできるファイルフォームフィールドを追加します。
  • fileフィールドを含むフォームを処理するコントローラーの強力なパラメーターのリストにmodel属性を追加します。CarrierWaveでは、添付ファイルを持つ必要があるモデルに特定の属性を追加する必要があります。 たとえば、avatarイメージを添付する必要があるUserモデルには、Stringである:avatarという属性が必要です。 これには、基になるデータベース列を追加するためのデータベース移行に加えて、モデル内のその属性にUploaderクラスを作成してマウントする必要があります。

    これは特に面倒ではありませんが、ActiveStorageはケースバイケースではるかに少ないコードを必要とします。

    もう一つ強調すべき点は、私のアプリであるMy Bucket Listアプリでは、CarrierWave avatar uploaderがデフォルトの単純なファイルストレージで設定されていることです。 順番に、アップロードされた画像は、アプリケーションのpublic/フォルダ内のどこかに保存されます。 その正確なパスは、アバターのUploaderクラス内で定義され、"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"に設定されます。 これはpublic/フォルダに対する相対パスであるため、アップロードされた画像はwebサーバーを介して直接アクセスできます。 これにより、添付ファイルへの直接アクセスが可能になり、後でActiveStorageと対比することができます。

    Railsのアップグレード

    ActiveStorageを見る前に、Rails5.2にアップグレードする必要があります。 これは、アプリケーションの複雑さに応じて、かなり複雑になる可能性のあるタスクです。 私がここで使用しているアプリケーションは、WADプログラムで構築していますが、更新するのは特に難しくありませんが、それでも注意と注意が必要で私のバケットリストアプリケーションをRails5.1からRails5.2に更新するために私がしたことは次のとおりです。

    最初に、私はアップグレードを分離するために私のgitリポジトリに新しいブランチを作成しました—アップグレードプロセスで何かがゆがんでしまった場合、アプリの以前の作業バージョンに戻ることができることが重要です!新しいブランチで、GemfileのRailsのバージョンを'~> 5.1.2'から'~> 5.2.0'に変更し、bin/bundle update railsを実行しました—このコマンドは、新しいバージョンのrailsとアプリケーション内のすべての関連 私のアプリケーションでは、gemの競合はありませんでしたが、サードパーティのgemを使用している場合は、この時点で異なるgemバージョン間の競合を解決す

    新しいRails gemとその依存関係をインストールした後、アプリケーション自体を更新する必要があります。 私はbin/bundle exec rails app:updateを使ってこれをしました。 このコマンドは、Rails5.2で動作するように、アプリケーション内の必要なすべてのファイルをプログラムで更新します。

    しかし…このコマンドは、config/routes.rbなどのアプリケーションに加えた変更を上書きします。 幸いなことに、コマンドは各ファイルを上書きするかどうかを尋ね、このプロセス中にdiffこれらのファイルのいずれかが上書きされるかどうかを 各上書きのプロンプトはです。:

    • Y “はい、私のファイルを上書きする”の場合、Enterを押すだけの場合のデフォルトオプションです。
    • n“いいえ、ファイルを上書きしないでください”
    • a “はい、このファイルを上書きし、他のすべてのファイルも上書きします!”. (私の一般的なルールは決してaを使用しません)。
    • q“このプロセスを終了します”の場合”
    • d “自分のファイルと上書きの違いを表示する”の場合”
    • hYnaqdhの意味のリストを表示する”の場合”

    私のアプリケーションでは、config/routes.rbconfig/locales/en.ymlを除くYで各上書きを受け入れました。 これら2つのファイルは私が変更したファイルだったので、私は自分のバージョンを維持したいので、nを選択しました。

    このアップグレードプロセスは、より複雑なアプリケーションがある場合、特に環境設定ファイルに多くのカスタム設定がある場合、より複雑にな config/environments/production.rbconfig/environments/test.rb、およびconfig/environments/development.rb。 アップグレードはこれらのファイルに重要な設定を追加しますが、独自のカスタム設定を維持することもできます—これは、別のgitブランチにアプリケーシ その後、この古いブランチのコードで、アップグレード後にすべてのアプリケーションコードと構成がまだ配置されていることを確認できます。

    bin/bundle exec rails app:updateを実行した後、bootsnap宝石をGemfileに追加する必要がありました。 これはRails5.2で使用されている新しいgemですが、app:upgradeコマンドの一部として追加されていません。 だから私はちょうどgem 'bootsnap'Gemfileに追加してからbin/bundle installを実行しました。

    この後、私のバケットリストアプリケーションはrails serverを使用する前と同じように起動しました。

    CarrierWaveをActiveStorage

    に置き換えるので、アプリケーションがRails5.2で実行されているので、CarrierWaveをActiveStorageに置き換えることができます。ActiveStorageでは、CarrierWaveで必要な添付ファイル名を格納するためにモデル固有の属性を追加する必要はありません。 ActiveStorageは、すべての添付ファイルに対して同じ2つの関連テーブルで動作します。これらの2つのテーブルを設定するために、私は実行しましたbin/bundle exec rails active_storage:installその後にrails db:migrate。 2つのテーブルはactive_storage_blobsactive_storage_attachmentsで、1つ目は添付ファイルの詳細、2つ目は添付ファイルをモデルレコードにリンクするポリモーフィック結合テーブルです。これらの2つのテーブルを作成したら、モデルに添付ファイルを含めるために他の移行を作成する必要はありません! これにより、ActiveStorageはデータベースの観点から簡単に操作できます。

    次に、:avatar添付ファイルの実装をCarrierWaveではなくActiveStorageに置き換えることを検討しました。 私のアプリでは、各Userには:avatarがあります。 以前はCarrierWaveを使用していたため、:avatar属性をUserモデルのCarrierWaveUploaderにマウントし、次のように宣言しました:

    class User < ApplicationRecord
    # ... various codez mount_uploader :avatar, AvatarUploader # ... other codez
    end

    CarrierWave:avatar添付ファイルは、次のようにhas_one_attached :avatarを使用してActiveSupport添付ファイルに置き換えることができます:

    class User < ApplicationRecord
    # ... various codez # commented old uploader for reference
    # mount_uploader :avatar, AvatarUploader
    has_one_attached :avatar # ... other codez
    end

    これは1行のコードへの変更です。 この時点で、他に何をする必要がありますか? たとえば、アップロードの保存場所はどのように設定されていますか? 私のアプリでは、CarrierWave avatar uploaderはデフォルトの単純なファイルストレージで設定されており、この場所はavatar_uploader.rbファイルで明示的に設定されていることに注意して 単純なファイルストレージもActiveStorageのデフォルトです。 この場所はconfig/storage.ymlファイル内で設定され、ローカルアップロードのデフォルト値が設定されます。ActiveStorageのデフォルト設定は、アプリケーションの変更された:avatar属性に対してアップロードが機能するためのコードを記述する必要がないことを意味します。 アップロードメカニズムをCarrierWaveからActiveStorageに完全に変更しましたが、これ以上何もする必要はありません: :avatarはすでに強力なパラメータとして宣言されているため、アップロードを管理するコントローラに変更を加える必要はありません。 また、これは:avatar“属性”によってサポートされているため、ユーザーがアップロードする画像を選択できるようにするビューのファイルフォームフィールドを変更する必しかし、CarrierWaveからActiveStorageに移行するために必要な変更がもう1つあり、それがビューで添付された画像を使用する方法です。 CarierWaveでは、avatar_urlメソッドを使用してフルイメージパスをレンダリングしました。 ActiveStorageでは、ファイルURLはattachment属性自体からレンダリングされるのではなく、ヘルパーメソッドに属性を渡すことによってレンダリングされます。 したがって、完全な添付URLはurl_for(user.avatar)を使用してレンダリングするか、image_tagで直接レンダリングすることができます。

    添付ファイルが存在するかどうかを明示的に確認する必要があるため、ビューでの完全な使用法は次のようになります:

    <% if current_user.avatar.attached? %>
    <%= image_tag current_user.avatar, class: 'avatar' %>
    <% else %>
    <%= image_tag 'default-avatar', class: 'avatar' %>
    <% end %>

    上記のようなスニペットを使用してビューのuser.avatar_urlへの参照を更新すると、すべての新しいアップロードのためにCarrierWaveからActiveStorageに完全に移動しました。

    古いCarrierWaveコードを整理する必要があり、CarrierWaveで行われた既存のアップロードをどうするかについての質問があります。 しかし、それについては以下を参照してください…

    より複雑なシナリオ

    ほとんどすべての本番シナリオは、私が上で概説したものよりも複雑になります。 アップロードがCdnやAWS S3のようなリモートサーバーに保存されていることや、サムネイルの画像サイズ変更などを考慮する必要があります。 ActiveStorageは、私たちも箱から出してそれらのことの多くを行うことができ、非常によく開発者のニーズのために設計されているようです。 ご想像のとおり、Railsガイドには良いドキュメントがあります。

    既存のアップロードをCarrierWaveからActiveStorageに移行することに関しては、これは比較的小さなrakeスクリプトで確実に可能です。 私は将来の記事でそれをカバーすることを目指します。

    これは単純なシナリオでしたが、全体的にActiveStorageを利用してCarrierWaveを置き換えるのがいかに簡単かに本当に満足していました。 私はまた、ActiveStorageのさまざまな部分に入った考えが好きです。 私は間違いなくあなたのアプリケーションでファイルアップロードにActiveStorageを使用するためにRails5.2に入る価値があると思います!

    詳しくはこちら!

    RubyとRuby on Railsについての詳細を学ぶことに興味がありますか? 私は、データサイエンス、webアプリケーション開発などのデジタルスキルを教える認定されたオンライン学習プラットフォームであるEPFL Extension SchoolでWebアプリケー EPFLは世界有数の大学の1つであり、Times Higher Education Rankingによって「No.1Young University」にランクされています。



+