コマンド入力の際の bundle exec , bin/ について

ターミナルでコマンドを入力する際、
$bundle exec ~~~$bin/~~~などの打ち方がある。
それぞれの用途についてまとめる。

$ bundle exec

  • これをつけた場合、プロジェクト内のgemが反映される。
  • つけない場合、システム全体のgemが反映され、バージョンの違いによるエラーが発生したりする。

$ bin/

  • これをつけた場合、プロジェクト内のbinフォルダ内のファイルが呼び出される。

例) bin/rails

#!/usr/bin/env ruby
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'

3行目に着目。
config/boot.rb

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)

require 'bundler/setup' # Set up gems listed in the Gemfile.
require 'bootsnap/setup' # Speed up boot time by caching expensive operations.

これにより、プロジェクト内のGemfileが読み込まれる。
すなわちbundle execと同様。

  • railsコマンドだけ、そのまま入力した時自動的に bin/rails と入力した時と同じ挙動をするようになっている。

まとめ

  • binフォルダ内にないコマンド
    →bundle exec
  • binフォルダ内にあるコマンド
    →bin/
  • rails コマンド
    →そのままでも良い

.gitignoreによるバージョン管理からの除外設定

.gitignoreファイルとは

バージョン管理システムGitで、管理下に置きたくないファイルを指定するためのファイル。

どんなファイルを除外するのか
  • 自動作成されるファイル
  • 共有すべきでないファイル
  • 容量が大きすぎるファイル など
使い方

ファイルは自分で作成。 $ touch .gitignore
特徴として以下の点がある。

  • リポジトリのどの階層にあっても良い。
  • どうリポジトリ内に複数あっても良い。
  • 複数ある場合、より深い階層にある.gitignoreファイルの内容が優先される。
書き方

.gitignoreがあるディレクトリ以下の全ファイル、ディレクトリを対象にできる。

ワイルドカード

当てはまるファイル、ディレクトリをまとめて除外または限定して除外することができる便利な記述方法。

* .../以外の0文字以上の文字列として使える
例)
directory/*...該当ディレクトリ下の全ファイル名が当てはまる
*.html ...拡張子がhtmlである全ファイル名が当てはまる

** ...0個以上のファイル、ディレクトリとして使える
例)
/a/** → /a, /a/x, /a/x/yなどにマッチ
/**/b → /b, /x/b, /x/y/bなどにマッチ
/a/**/b → /a/b, /a/x/b, /a/x/y/bなどにマッチ

Railsビューヘルパー

railsビューヘルパーを使ってHTMLコードを書く。
コードに統一感が出せる。

content_tag

  • 使い方
    content_tag(タグ名, 'コンテンツ', オプション, エスケープ)

contet_tag(:div, 'happy', class: 'text')  
=> "<div class="text">happy</div>"
  • 注意点
    コンテンツの中身がなくてオプションを記述する場合は、第2引数にnilを渡す。
content_tag(:div, nil, class: 'text')  
=> "<div class="text"></div>"

tag

  • 使い方
    tag.タグ名 'コンテンツ', オプション

tag.div 'happy', class: 'text'  
=> <div class="text">happy</div>
  • 注意点
    タグ名の後に,(カンマ)は書かない。
    content_tagと違いコンテンツがない場合は省略して良い。
tag.div class: 'text'
=> <div class='text'></div>

tagの方が使い勝手良さそう。

find_each

使い方

eachとほぼ同じ。

オプション
  • :batch_size …同時処理数
  • :start …処理開始位置
  • :finish …終了キー
  • :error_on_ignore …例外を発生させる
メリット

デフォルトでレコードを1000件ずつ分割して処理する。
なのでeachよりもメモリの消費が少ない。

まとめ

対象データが1000件以上であればfind_eachを使い、それ以下ならばeachで良い。

rspecテスト内におけるタブ(ウィンドウ)の切り替え

実装方法

switch_to_window(windows.last)

概要

  • テストコード
describe ~~
  context ~~
    it ~~
      click_link ~~
  • クリック動作対象のコード
<a href="~~" target="_blank">

target="_blank"により、リンクがクリックされたら新規タブで開かれる。

しかしテストコード内では自動でタブの切り替えが行われないため、それ以降のテストの対象ページがclickしたページ(元いたページ)になってしまう。

そうならないようにちゃんとクリックによりできた新規タブに移動させる必要がある。

click ~~~
switch_to_window(windows.last)

click動作直後に記述。 これにより最後に開かれたすなわち新規タブに移動することができる。

seleniumのコードみたい。

let let! beforeの使い分け

役割

let,let!
  • 変数の作成
before
  • 変数の作成
  • メソッド等の実行
let(:user) { create(:user) }
let!(:user) { create(:user) }
before do
  @user = create(:user)
  visit login_path
  login_as(@user)
end

評価されるタイミング

let
  • 変数が呼び出された時(遅延評価)
let!, before
  • 各ブロックの前(事前評価)
let(:user) { create(:user, name: 'hogehoge') }
~~~(省略)~~~
expect(user.name).to eq 'hogehoge'

expect(user.name)の時点ではまだ評価されていないのでuserはnilであり、失敗する。 こういった場合にはlet!を使用する。

FactoryBot.の省略

実装方法

spec/rails_helper.rb

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

を記述すれば良い。

環境
  • taskモデルのバリデーションチェックテスト
  • FactoryBotを使ってtaskモデルのオブジェクトを作成済
実装前

spec/model/task_spec.rb

require 'rails_helper'

RSpec.describe Task, type: :model do
  describe 'validation' do
    it 'is valid with all attributes' do
      expect(FactoryBot.build(:task)).to be_valid
    end
  end
end
実装後
require 'rails_helper'

RSpec.describe Task, type: :model do
  describe 'validation' do
    it 'is valid with all attributes' do
      expect(build(:task)).to be_valid
    end
  end
end

rails以外の実装方法もここにまとめられている。