LoginSignup
2
1

More than 3 years have passed since last update.

Rails6 のちょい足しな新機能を試す15(Active Storage編)

Last updated at Posted at 2019-05-14

はじめに

Rails 6 に追加されそうな新機能を試す第15段。 今回のちょい足し機能は、 Active Storage 編です。
というか今回は Active Storage のバグフィックスじゃないかと思ってます。

Rails 5.2 では、model で validation のエラーが起ってもファイルがアップロードされていました。
Rails 6.0 では、model がDBに保存されるとファイルがアップロードされるようになっています。
実際に試した方がわかりやすいです。

記載時点では、Rails は 6.0.0.rc1 と 5.2.3 で確認しました。Rails 6.0.0.rc1 は gem install rails --prerelease でインストールできます。

基本的な試し方は、5.2.3 でも 6.0.0rc1 でも同じです。

$  rails --version
Rails 6.0.0.rc1

Rails プロジェクトを作る

$ rails new sandbox6_0_0rc1
$ cd sandbox6_0_0rc1

scaffold で User を作る

$ bin/rails g scaffold User name

Active Storage を使う準備をする

$ bin/rails active_storage:install

User モデルを編集する

User モデルとアップロードファイル(今回は画像ファイル)を紐づけるため has_one_attached を使います。
また、name に validation を追加します。

app/models/user.rb
class User < ApplicationRecord
  has_one_attached :avatar
  validates :name, presence: true
end

view を編集する

ファイルをアップロードできるように _form.html.erb を編集します。

avatar 用の form.file_field を追加します。

app/views/users/_form.html.erb
<%= form_with(model: user, local: true) do |form| %>
  ...
    <%= form.text_field :name %>
  </div>

  <div class="field">
    <%= form.label :avatar %>
    <%= form.file_field :avatar %>
  </div>

  <div class="actions">
  ...
<% end %>

アップロードされた画像ファイルを表示できるように show.html.erbimage_tag を追加します。

app/views/users/show.html.erb
...
  <%= @user.name %>
</p>

<p>
  <strong>Avatar:</strong>
  <% if @user.avatar.attached? %>
    <%= image_tag @user.avatar %>
  <% end %>
</p>
...

controller を編集する

ブラウザからパラメータとして渡されてくる avatar をUserモデルに渡せるように :avatar を追加します。

app/controllers/users_controller.rb
  private:
    ...
    # Never trust parameters from the scary internet, only allow the white list through.
    def user_params
      params.require(:user).permit(:name, :avatar)
    end

DBのmigration を実行する

$ bin/rails db:create db:migrate

rails s を実行する

$ bin/rails s

動作確認する

ブラウザで http://localhost:3000/users/new にアクセスします。

アップロードする画像ファイルを選択します。
validation error となるように name は何も入力しません。

Create User ボタンを押してみます。

Name can't be blank'

のエラーになります。
ここまでは、Rails 5.2.3 でも Rails 6.0.0rc1 でも同じです。
ここで、別のコンソールで、 storage ディレクトリを確認してみましょう。

Rails 5.2.3 では、サブディレクトリができてファイルもできています。

$ ls -lR storage
storage:
total 4
drwxr-xr-x 3 suke suke 4096  5月 11 15:36 49

storage/49:
total 4
drwxr-xr-x 2 suke suke 4096  5月 11 15:36 gT

storage/49/gT:
total 12
-rw-r--r-- 1 suke suke 9502  5月 11 15:36 49gTM2NXg8UsKPVqTSuMNXCz

Rails 6.0.0rc1 では、サブディレクトリはありません。

$ ls -lR storage
storage:
total 0

Rails 5.2.3 では、登録画面で、ファイルを指定して、validation エラーを起こす度に、 storage ディレクトリの中にファイルが増えていきます。
Rails 6.0.0rc1 では、DBに保存できた時に初めて、 storage ディレクトリの中にファイルができます。

ソース

今回のソースは以下から参照できます。
https://github.com/suketa/rails6_0_0rc1/tree/try015_active_storage

参考情報

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1