Minitestコンフリクト問題

はじめに

明けましておめでとうございます。2019年はアウトプットの量を増やし、為になる技術ブログにしていきたい所存です。

今回の概要

「プロを目指す人の為のRuby入門」の第4章の課題写経中、エラーに遭遇しました。 作成中のプログラムはRubyメソッドをTDDで進めるシンプルなプログラムです。

テストコード

require 'minitest/autorun'
require './lib/rgb'

class RgbTest < Minitest::Test
  def test_to_hex
    assert_equal '#000000', to_hex(0, 0, 0)
    assert_equal '#ffffff', to_hex(255, 255, 255)
    assert_equal '#043c78', to_hex(4, 60, 120)
  end

  def test_to_ints
    assert_equal [0, 0, 0], to_ints('#000000')
    assert_equal [255, 255, 255], to_ints('#ffffff')
    assert_equal [4, 60, 120], to_ints('#043c78')
  end
end

コード

def to_hex(r, g, b)
  [r, g, b].inject('#') do |hex, n|
    hex + n.to_s(16).rjust(2, '0')
  end
end

def to_ints(hex)
  r = hex[1..2]
  g = hex[3..4]
  b = hex[5..6]

  ints = []

  [r, g, b].each do |s|
    ints << s.hex
  end
  ints
end

その際に、テストを実行すると

ruby test/rgb_test.rb

こんなエラーが出ました。

Traceback (most recent call last):
        13: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/minitest-5.11.3/lib/minitest.rb:63:in `block in autorun'
        12: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/minitest-5.11.3/lib/minitest.rb:121:in `run'
        11: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/minitest-5.11.3/lib/minitest.rb:92:in `load_plugins'
        10: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/minitest-5.11.3/lib/minitest.rb:92:in `each'
         9: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/minitest-5.11.3/lib/minitest.rb:98:in `block in load_plugins'
         8: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
         7: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'
         6: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.2.1/lib/minitest/rails_plugin.rb:4:in `<top (required)>'
         5: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:39:in `require'
         4: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:128:in `rescue in require'
         3: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems.rb:217:in `try_activate'
         2: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems.rb:224:in `rescue in try_activate'
         1: from /Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems/specification.rb:1437:in `activate'
/Users/sugiwaka/.rbenv/versions/2.5.0/lib/ruby/2.5.0/rubygems/specification.rb:2324:in `raise_if_conflicts': Unable to activate railties-5.2.1, because activesup
port-5.2.2 conflicts with activesupport (= 5.2.1) (Gem::ConflictError)

minitestはrdenvをローカル環境に入れた時点で自動的に導入されるのですが、どうやらバージョンコンフリクトを起こしている模様です。 (https://qiita.com/jnchito/items/1e928f8088b2cc6bd3fa)

Unable to activate railties-5.2.1, because activesup
port-5.2.2 conflicts with activesupport (= 5.2.1) (Gem::ConflictError)

上記リンクに記載されている解決法(自分は --no-pluginsコマンドを使いました)で、手元のエラーは解決したのですが、 minitestプラグインがどう読み込まれているか気になったので、確認してみます。→次回

🐤

パーシャルレンダリング(locals,collection)

①locals

パーシャルに、ローカル変数を引数として渡す事でパーシャルを柔軟にできる。

・index.html.erb

<h1>入力フォーム</h1>
<%= render partial: "form", locals: { point: @point }  %>

・edit.html.erb

<h1>編集フォーム</h1>
<%= render partial: "form", locals: { point: @point }  %>

・_form.html.erb

<%= form_for(point) do |f| %>
  <p>
    <b>Point name</b><br>
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

②collection

:collectionオプションを使用してパーシャルにコレクションを渡すと、コレクションのメンバーごとにパーシャルがレンダリングして挿入できる。

・index.html.erb

<h1>items</h1>
<%= render partial: "item", collection: @items %>

・_item.html.erb

<p>items Name: <%= item.name %></p>

🐤

Rails db:rollback

rails db:rollbackの際に、戻したいマイグレーションのステップ数は下記の通りに実行できる。

rails db:rollback  STEP = ステップ数

現行バージョンが下記のようであるとする。

20120415162250_create_titles.rb
テーブルの作成

20120416072618_add_details_to_titles.rb
nameカラムとhomeカラムの追加

20120416074444_remove_home_from_user.rb  <-- 現在のバージョン
homeカラムの削除

そこから

rake db:rollback STEP=2
== 20181031024118 CreateRemoveFromUsers: reverting ============================
-- drop_table(:remove_from_users)
   -> 0.0172s
== 20181031024118 CreateRemoveFromUsers: reverted (0.0212s) ===================

== 20181031023851 AddDetailsToUser: reverting =================================
-- remove_column(:users, :home, :text)
   -> 0.2622s
-- remove_column(:users, :name, :string)
   -> 0.1303s
== 20181031023851 AddDetailsToUser: reverted (0.3928s) ========================

そうすると、

20120415162250_create_titles.rb  <-- 現在のバージョン
テーブルの作成

20120416072618_add_details_to_titles.rb
nameカラムとhomeカラムの追加

20120416074444_remove_home_from_user.rb  
homeカラムの削除

となる。🐤

ネストリソース

作成しているRailsアプリにおいて、親子関係をもつモデルがあり、ルーティングで親子関係を表現したい場合などは あるリソースの配下に子リソースを置けばいい(ネストリソース)。

class Theme < ApplicationRecord
 has_many :categories
end

class Category < ApplicationRecord
  belongs_to :theme
end
resources :themes do
  resources :categories 
end

ネストリソースを使う事により、ThemesControllerにルーティングできるようになる。 その際にルーティングヘルパーも作成される。

theme_categories_url
edit_theme_category_path

など。

その際に、最初のパラメータとしてThemeモデルのインスタンスを1つ取ります (theme_categories_url(@theme))。 またネストリソースのネスティングは一回までにしておくのが無難。

ネストリソースをより、シンプルに記述する方法の一つに「:shallowオプション」がある。

コレクション(:idを持たないアクション)のみを親スコープで定義する。 メンバー(:idを持つアクション)はネストに含めない。

resources :themes do
  resources :categories, only: [:index, :new, :create]
end
resources :categories, only: [:show, :edit, :update, :destroy]

これを:shallowオプションを使うと

resources :themes do
  resources :categories, shallow: true
end

また親リソースで:shallowオプションを指定すると、すべてのネストしたリソースが浅くなる。

resources :themes, shallow: true do
  resources :categories
  resources :comments
  resources :likes
end

下記も上記と同じ。

shallow do 
resources :themes
  resources :categories
  resources :comments
  resources :likes
end

また浅いルーティングカスタムする二つのscopeメソッドが存在する。

①:shallow_pathオプション →指定されたパラメータをメンバーのパスの冒頭にだけ追加する。 (例: standard/categories/:id(.:format))

scope shallow_path: "standard" do
  resources :themes do
    resources :categories, shallow: true
  end
end

②:shallow_prefixオプション →指定されたパラメータを (パスではなく) メンバーの名前付きヘルパー名の冒頭に追加する。 (例: standard_categories_path)

scope shallow_prefix: "standard" do
  resources :themes do
    resources :categories, shallow: true
  end
end

🐤

参照 :Rails guide

Git コミットメッセージについて

gitコミットの際は命名に気をつけるべきだと今更反省。

分かりやすいコミットメッセージの付け方について調べてみた。

①種類

[Add]   => 新規機能追加
[Remove]=> 削除
[Update]=> 機能修正
[Fix]   => バグ修正
[Clean] => リファクタリング

など。

②コミットメッセージ

-変更内容の要約を簡潔に書く事
-変更は命令系で記載
-50字以内
(例)

-[Remove] some dead code(不要なコードの除去)
-[Add] build script(ファイル追加)
-[Fix] typos(タイポ修正)
-[Update] User controller(機能修正)

③その他注意点

-粒度は細かく、git add-pを使う
-git -log online

🐤