プログラミング初学者なしこの技術アウトプット

プログラミングスクールRUNTEQで学んだことや自習したことのアウトプットをするブログ

rails g controller 実行時にDeprecation Warningになった場合の解決法

ActionMailerでメイラーの生成をするためにRailsガイドに従ってbundle exec rails g mailer UserMailerをしたらDeprecation warningが出ました。 他のrails gコマンドでも同様の事象が起きました。

警告の内容
Deprecation warning: Expected string default value for '--test-framework'; got false (boolean).
This will be rejected in the future unless you explicitly pass the options `check_default_type: false` or call `allow_incompatible_default_type!` in your code
You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.

以下の記事を参考に、解決ができました!
rails g controller 実行時にDeprecation Warningになった。その対処法。

  1. Gemfileにgem 'thor', '0.19.1'を追加

  2. bundle update thorを実行

簡単でした! 記事によると、結構前からある事象らしく、ジェネレータに関係のあるthor gemのバージョンが関係していて、'0.19.1'`にダウングレードすることで表示されなくなるみたいです。

CarrierWaveで複数画像扱うときは配列形式で保持する必要がある

seedファイルでuserとpostのダミーデータを以下の内容で作成しbundle exec rails db:seedで実行したところ、postsの生成のところでArgumentError: invalid byte sequence in UTF-8が出て生成が失敗してしまいました。

#usersのseedファイル

puts 'Start inserting seed "users" ...'
10.times do
  user = User.create!(
    email: Faker::Internet.unique.email,
    username: Faker::Internet.unique.user_name,
    password: 'password',
    password_confirmation: 'password'
  )
  puts "\"#{user.username}\" has created!"
end
#postsのseedファイル

puts 'Start inserting seed "posts" ...'
User.limit(10).each do |user|
  post = user.posts.create!(
    body: Faker::Hacker.say_something_smart,
    images: File.open("#{Rails.root}/db/fixtures/dummy.png")
  )
  puts "post#{post.id} has created!"
end

原因

調べたところこちらのサイト( carrierwaveを使った画像のseed方法 )のものと同様で、CarrierWaveで複数画像扱うように設定していたので画像は配列形式で格納しなければならなかったということでした。

対応内容

postsのseedファイルの
images: File.open(“#{Rails.root}/db/fixtures/dummy.png") の部分を下記のように配列形式に変更しました。
images: [File.open("#{Rails.root}/db/fixtures/dummy.png")]

これで無事ダミーデータが生成されました!

CarrierWaveで複数画像を扱う場合


・画像情報を格納するカラム名を複数形にする。(image => images)

・データベースがjsonのデータ型をサポートしている場合(PostgreSQL, MySQLなど)はデータ型をJSONにする。

#例
  def change
    create_table :posts do |t|
      t.json :images, null: false
      t.text :body, null: false
      t.references :user, foreign_key: true

      t.timestamps
    end


データベースがjsonのデータ型をサポートしていない場合(SQLiteなど)はstring型にし、モデル側でserialize :images, JSONと記載する。

#例
class Post < ApplicationRecord
  belongs_to :user
  mount_uploaders :images, PostImageUploader
  serialize :images, JSON

  validates :images, presence: true
  validates :body, presence: true, length: {maximum: 1000}
end


・モデルとアップローダーとの紐付けの設定の際、モデルにmount_uploaders(複数形) :images(カラム名複数形), PostImageUploader(アップローダー名)のように複数形にして記載する。
・コントローラ上のストロングパラメータも画像の部分は空の配列を記載する

params.require(:post).permit(:body, images: [])


・ビュー上の画像を選択するフィールドにはmultiple: trueで複数選択できるようにする。

(例)
= f.file_field :images, multiple: true, class: 'form-control'

( GitHub - carrierwaveuploader/carrierwave: Classier solution for file uploads for Rails, Sinatra and other Ruby web frameworks )

( CarrierWaveで複数画像をアップロードする[SQLite][Heroku] - Qiita )

.DS_Storeについて

開発を進めてgit add . をしたらその中に見覚えのない「.DS_Store」というファイルが突然出現しました。

調べたところ、.Ds_Storeとは、Macでファイルを作成するたびに、Macのシステムが各ディレクトリに自動生成するシステム情報ファイルらしい。
( DS_STOREとは?WindowsでDS_STOREファイルを作らない方法を解説! | アプリやWebの疑問に答えるメディア )
gitignoreするべきか講師の方に聞いたところ、gitignoreしても大丈夫ですがいろんなディレクトリにできると思うのでそれをいちいちgitignoreに書くのは面倒そうなので、そのままコミットしてプッシュしちゃっても大丈夫。とのことだった。
そもそも生成されないようにする方法もあるみたいですが、今回は練習も兼ねて一応gitignoreして対応することにしました!

対応内容

  1. gitignoreに.DS_Storeを追加記載 ( .gitignoreで.DS_Storeを削除しよう - Qiita )
  2. 'git rm --cached .DS_Store'で既に管理対象に追加されてしまっていたファイルを管理対象から外した ( 【Git】git rm --cached [ファイル名]:ファイルを管理対象から除外する - Qiita )

rails new時、--skip-testするとtestディレクトリ自体が生成されない

課題のアプリを作成中に、自分のアプリにはtestディレクトリが作成されているが課題の解答例にはなかったので確認したところ、解答例の方はrails new時、--skip-testしていることがわかった。

railsの場合、デフォルトだとMinitestのファイルが作成されてしまうので、RSpecを使っていく場合、 --skip-testのオプションをつけるといいということを学んだ!

参考( rails new した時の --skip-test と --skip-system-test の違い · GitHub )

dump.rdbがカレントディレクトリに作成されてしまう問題

redisを導入したら、dump.rdbというファイルが生成されたのでgitignoreした方がいいのか講師の方に聞いたところ、そもそもカレントディレクトリに作られてしまうのがよろしくないのでredisの設定を変えた方がいいとのアドバイスを頂きました!

調べたこと

Redisはインメモリデータベースであるため、サーバプロセスが終了するとメモリ上のデータも消えてしまう。サーバプロセス終了後もデータを保持するための機能がRDBというもの。

Redisでは特定の時点のスナップショットをRDBファイル(データベースのダンプファイル)として保存することができる。
( https://www.sraoss.co.jp/tech-blog/redis/redis-persistdata/ )

対応内容

dump.rdbがカレントディレクトリに生成されてしまう - blog.kotamiyake.me
上記のサイトを参考に以下の手順を実施。

1. /usr/local/etc/redis.confの設定を確認し、以下の通り/usr/local/var/db/redis/にdump.rdbが生成される設定になっていることを確認しました。

/usr/local/etc/redis.conf

~~略~~~

# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir /usr/local/var/db/redis/
~~略~~~

2. 実際の設定はどうなっているのか確認。ここがカレントディレクトリになっていました。

% redis-server
% redis-cli       
127.0.0.1:6379> config get dir
1) "dir"
2) "/Users/natsumimatsuda/workspace/menta!/insta_clone/insta_clone_by_me"

3. この参考サイト曰く、そもそもredis-serverの起動時に設定ファイルのパスを指定してあげる必要があったようなので

% redis-server /usr/local/etc/redis.conf

としたら、ちゃんと設定通りの場所にdump.rdbファイルが生成されるようになりました。

% ls /usr/local/var/db/redis/
dump.rdb

% redis-serverで起動するとカレントディレクトリに生成されてしまうので、% redis-server /usr/local/etc/redis.confで起動するようにし、更に念の為gitignoreのdump.rdbを追加しておきました。

rubocopコマンドを実行したらrubocop: command not foundのエラーが出た

rubocop導入の際、gemfileに記載% bundle install --path vendor/bundle% rubocopと実行したところ、以下のようなエラーが出ました。

エラー

rbenv: rubocop: command not found 
The `rubocop' command exists in these Ruby versions: 2.6.5

作業アプリのrubyバージョンの状態

% rbenv versions
  system
  2.6.3
* 2.6.4 (set by /Users/XXXXXXXX/workspace/insta_clone/.ruby-version)
  2.6.5
  2.6.6


そこでこの記事( VScodeでrubocopを使ったらエラーが出た - Qiita )を参考にし、デフォルトのruby環境にrubocopがインストールされていないと推測し、

% gem install rubocop
% gem install rubocop-rails 

と実行した後、% rubocopとしたらrubocopがちゃんと走ってファイルが解析されました!
ただ、その後、この記事( bundlerでインストールしたgemをコマンドラインで実行するにはbundle execをつける - Just do IT )を見つけ、bundlerでインストールしたgemをコマンドラインで使う場合、文頭にbundle execを付ける必要があると書いてあったので% bundle exec rubocopしてみたら上手くいったかもしれませんが・・

いずれにせよ解決してよかったです。

rubocop導入の際のgemの書き方

rubocop導入の際のgemの書き方についてわかったことを書いておきます!

参考サイト( https://qiita.com/terufumi1122/items/ad55bf8713c0df053f58 )で、

バージョン0.72以降のgemは
rubocop:生Rubyに関わる構文規則チェック
rubocop-railsRailsに関わる構文規則チェック

のように細分化が行われていると書かれていたので、rubocop導入の際はバージョンを確認しつつ、gemfileに

gem 'rubocop', require:false
gem 'rubocop-rails', require:false

と入れておけばいいという理解をしました!

require:falseに関して
これをつけるとbundlerによってRailsアプリ側に自動で読み込みされないようになるということらしいです。
Bundlerに普通に書くと、Gemfileに書いたgemを、自動でまとめてrequireするような仕組みとなっているけど、rubocopやRSpecのようにテスト専用のGemの場合、実運用のときにrequireしても無駄にしかならないので、require: falseとして、開発者がターミナル等で必要に応じて手動で使用するようにするみたいです。

手順としては、gemfileに記載bundle install --path vendor/bundlebundle exec rubocopで使用ができます。
また、rubocop.yml上で規定の変更の設定ができます。