【エラー解決】An error occurred while installing rugged (1.6.3), and Bundler cannot continue.

環境構築をしているプロジェクトで、依存関係があるrugged gemが入らないため、解決するまで試したことを書き残していきます。

エラーをちゃんと読む

$ bundle install
...(省略)
Installing rugged 1.6.3 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

...
checking for gmake... no
checking for make... yes
checking for cmake... yes
checking for pkg-config... no
ERROR: pkg-config is required to build Rugged.
...

An error occurred while installing rugged (1.6.3), and Bundler cannot continue.
  • gmakeがnoになっている?
  • Rugged をビルドするには pkg-config が必要らしいですね。

requiredと言われているのでpkg-configの方から解決してみる

まずpkg-configってなんだ => pkg-configは、ライブラリやヘッダーファイルの依存関係を管理するためのツールらしい。

configファイルとかそういうのじゃないのか。。

とりあえずインストールしてみる

macのためHomebrewでインストール

$ brew install pkg-config

bundle install 再実行

該当のプロジェクト配下で実行

$ bundle install

まとめ

実は最初戸惑って適当に調べてました。ちゃんとエラー読んで、何が足りないのか調べた方が楽できますね。

急がば回れです。

【Rails】俺好みのrails new備忘録

rails new して色々試すときにあれ?いつも何やるっけってことをなくすために、rails newのときによくすることを備忘録として残しました。

rails new

rails new sandbox -d postgresql -j esbuild --css bootstrap --skip-test

I18n

  class Application < Rails::Application
    ...
    # デフォルトタイムゾーンを日本時間に
    config.time_zone = 'Tokyo'
    # Railsアプリのデフォルト言語を日本語に
    config.i18n.default_locale = :ja
# config/localesにja.ymlをダウンロード
curl -s https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -o config/locales/ja.yml

html2hamlでerbをhaml

globalにインストールしているhtml2hamlをプロジェクト配下で実行。

GitHub - haml/html2haml: Convert HTML and HTML+Erb to Haml.

find . -name \*.erb -print | sed 'p;s/.erb$/.haml/' | xargs -n2 html2haml

gem

gem 'devise'
gem 'simple_form'
gem 'haml-rails'
gem 'enumerize'

group :test do
  ...
  gem 'rspec-rails'
  gem 'factory_bot_rails'
end

rspec

# rspecの設定ファイルをインストール
rails generate rspec:install
# 不要なファイルが自動生成されない
config.generators do |g|
  g.test_framework :rspec,
                   view_specs: false,
                   helper_specs: false,
                   routing_specs: false
end
# RSpec 関連の設定ファイルを spec/support ディレクトリに配置する設定
# コメントアウトを外す
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }

devise

# deviseの設定ファイルをインストール
rails generate devise:install
# 例)deviseでUserモデルを作成
rails generate devise User

deviseでユーザー登録を行う際に入力したメールアドレスにメールを送り、登録を完了させるという機能を追加できる。メールに記載するURLのドメイン名をあらかじめ設定しておく必要がある。

Rails.application.configure do
  # 以下を追記
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end

simple_form

# プロジェクトにbootstrapのアセットを適用したsimple_formを適用
rails generate simple_form:install --bootstrap

終わりに

忘れていることもあるかもしれないので、思い立ったら追記していこうと思います。

参考

gem

ブログ

git commitの前に「動作確認した?」のメッセージを表示してみた

よっしゃ実装完成したー!コミットしよー。って短絡的にコミットやプッシュをしたことありませんか? 人間はミスが多い生き物ですし、自分は特にミスをするタイプです。

そんな人間は実装した後に、きちんと動作確認するべきですが、動作確認すらも簡単にしちゃうこともありますよね。 それを少しでも防ぐ仕組みを作りたい!

ってことで「動作確認した?」をコミット時のメッセージに表示してみます。

globalなgit-hooksを設定

# git-hooks/hooks`ディレクトリを作成(ディレクトリ名は何でも可)
$ mkdir -p git-hooks/hooks
# pre-commitファイルを作成
$ touch git-hooks/hooks/pre-commit
# 実行権限を付与
$ chmod a+x git-hooks/hooks/pre-commit

pre-commitを以下のように編集

#!/bin/bash

exec < /dev/tty
read -p "動作確認済みですか?"

作成したディレクトリをhooksに設定

$ cd git-hooks
# core.hooksPathに~/git-hoos/hooksを設定
$ git config --global core.hooksPath $(pwd)/hooks
# この時点でgit config -lを見てみるとcore.hookspathに登録されています
$ git config -l   
...
core.hookspath=/Users/makky/git-hooks/hook
...

これだけでOK。

試してみる

$ cd ~
# 適当なプロジェクトを作りコミット
$ mkdir git-hooks-test
$ cd git-hooks-test
$ git init
$ touch sample.txt
$ git add sample.txt
$ git commit -m 'git hooks test'

成功しました。Enterを押したら正常にコミットされます。大満足。

終わりに

今回は簡素にコミット時にうっかりを防ぐための対策をしてみましたが、もっとイケてる感じに対策ができたら投稿してみたいと思います。

参考

【Rails】deliver_laterで送信したはずのメールがletter_openerでプレビューできない

困ったこと

すでに開発されているプロジェクトで.deliver_laterを使ってメールを送信している箇所がletter_openerでプレビューされなかった。

deviseを使った招待メールはプレビューで確認できているのに。。

結論

ローカル環境でジョブの実行がされていなかったことが原因。

delayed_jobを使っているプロジェクトの場合はrake jobs:workでジョブの実行したら、今まで送信されていなかったメールが一気に送信されました。

学び

deliver_laterメソッド

Railsガイドの説明

deliver_laterを使うと、Active Jobによるメールキューにメールを登録できます。これにより、コントローラは送信完了を待たずに処理を続行できます。

つまり以下のようなアクション内のコードで.deliver_laterの処理は遅延されずに実行することができます。

class UsersController < ApplicationController
  def send_email
    user = User.find(params[:id])
    UserMailer.welcome_email(user).deliver_later
    # この時点でメールは非同期に送信され、処理はすぐに続行される
    ...
  end
end

実際にdeliver_later後のdelayed_jobsテーブルを確認すると、キューのレコードが生成されています。

rake jobs:workでジョブの実行していたら、このキューが実行されるというわけですね。。

参考

ターミナルのプロンプトにgitの差分(diff)のステップ数を表示させたい

そもそもターミナルのプロンプトって?

「プロンプト」はターミナルの中でuser_name@host_name ~ %で表示される、ユーザーにコマンドを入力するための待ち受け状態を示すテキストのこと。

なぜ差分(diff)を表示させたいのか

開発をしていると知らず知らずのうちにdiffが肥大化することがあり、大量の差分を持ったプルリクエストを作ってしまいます。肥大化する前に先輩エンジニアにレビューしてもらう環境を整えようとdiffを表示させてみます。

先に結果

以下のように表示させました。

差分がない時

差分が存在する時

方法

イケてないかと思いますが、目的は達成しています。以下のように~/.zshrcを編集しました。

autoload -Uz vcs_info
setopt prompt_subst
# gitのブランチ名等表示
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr "%F{yellow}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{red}+"
zstyle ':vcs_info:*' formats "%F{green}%c%u[%b]%f"
zstyle ':vcs_info:*' actionformats '[%b|%a]'

precmd () {
  vcs_info

  # git diff --shortstatのinsertion, deletionを抽出して表示する
  export GIT_DIFF_INSERTION=''
  export GIT_DIFF_DELETION=''
  if [ -n "$(git status --short 2>/dev/null)" ];then
    git_diff_stat=$(git diff --shortstat)
    if [[ $git_diff_stat == *insertion* ]];then
      export GIT_DIFF_INSERTION=+$(echo $git_diff_stat | sed -E 's/.*, (.*) insertion.*/\1/')
    fi
    if [[ $git_diff_stat == *deletion* ]];then
      export GIT_DIFF_DELETION=-$(echo $git_diff_stat | sed -E 's/.*, (.*) deletion.*/\1/')
    fi
  fi
}
PROMPT='%n@%m %c'\$vcs_info_msg_0_''
PROMPT=${PROMPT}' %F{green}${GIT_DIFF_INSERTION}%F{red}${GIT_DIFF_DELETION}
%f$ '

おわりに

今回は若干無理やり感はありますが、ターミナルのプロンプトにgitの差分(diff)のステップ数を表示させてみました。 シェルスクリプト使うのはまだ不慣れなので、イケてるzshrcがかけるようになってきたら更新する予定です。

【Ruby】all?メソッドで配列の要素が全ての条件を満たす場合を表現したい

はじめに

配列内の要素が特定の条件を満たすかどうかを判定する必要がある場面があると思います。そんな時に便利なのが、Rubyall? メソッドです。このメソッドは、配列内のすべての要素が指定した条件を満たすかどうかを一度に判定してくれます。この記事では、具体的な例を交えて all? メソッドの使い方を解説します。

all? メソッドの概要

all? メソッドは、Enumerable モジュールに含まれる便利なメソッドの一つです。このメソッドは、コレクション内の全ての要素に対して特定の条件を適用し、すべての要素が条件を満たす場合には true を、一つでも満たさない要素がある場合には false を返します。これにより、複数の要素に対し、条件を満たしているかどうかを素早く判定できます。

実際のコード例

例を通して、all? メソッドの活用方法を理解してみましょう。 ある教育系のサービスの中で教材が全て終わっているかどうか判定する例です。 以下のようにUser, Lesson, CompletedLessonモデルが存在し、UserのCompletedLessonがLessonに全て含まれているかをall?で判定します。

class User < ApplicationRecord
  has_many :completed_lessons
  has_many :lessons, through: :completed_lessons
end

class Lesson < ApplicationRecord
  has_many :completed_lessons
  has_many :users, through: :completed_lessons
end

class CompletedLesson < ApplicationRecord
  belongs_to :user
  belongs_to :lesson
end
# Userモデル内でメソッドを定義
class User < ApplicationRecord
  def all_lessons_completed?(user)
    all_lessons = Lesson.all
    completed_lessons = user.completed_lessons.pluck(:lesson_id)

    all_lessons.all? { |lesson| completed_lessons.include?(lesson.id) }
  end
end

まとめ

all? メソッドは、Ruby on Rails で配列内の要素が条件を満たすかどうかを一度に判定するのに便利なメソッドです。 ぜひ使ってみてください。

参考文献