一から勉強させてください

最下級エンジニアが日々の学びをアウトプットしていくだけのブログです

git-new-workdirを導入してGitのブランチを複数同時に扱えるようにした

今、僕の仕事環境では「エンジニアそれぞれが作業用ブランチを切って開発を進め、Github に pull-req を出してレビューもらって、それが通ったらマージされる」、といったよくありがちなフローで開発を進めています。

で、今までは自分が開発をしている最中に同僚から pull-req が飛んできてレビューをしなくてはならなくなったとき、自分の作業を一旦git stashなり、git commitなりしてキリがいい状態にしてから、git checkoutしてレビュー、、のようなことをやっていました。

ですが、最近同僚にgit-new-workdirなるものを使えばそんなだるいことしなくていいよーって教えてもらったのでさっそく導入!!今回はその導入メモです。

git-new-workdir コマンドを使えるようにする

僕はhomebrewで git を導入してるのですが、git-new-workdir自体はすでに/usr/local/share/git-core/contrib/workdir/git-new-workdirにありました。

ただ参考記事を見る感じだと、コマンドはパスを通すなり、シンボリックリンクを貼るなりしないと使えないようなので今回は

$ ln -s /usr/local/share/git-core/contrib/workdir/git-new-workdir /usr/local/bin/git-new-workdir

して使えるようにしました。これで

$ git-new-workdir

usage: /usr/local/share/git-core/contrib/workdir/git-new-workdir <repository> <new_workdir> [<branch>]

って出るようになりました!

ちなみにgit-new-workdirがない人はこことかから落としたりすれば大丈夫そうです。

実際に使ってみる

$ git checkout git@github.com:project_name.git(てきとーなproject)

$ git-new-workdir project_name for_develop
$ git-new-workdir project_name for_review

これで開発用のブランチで開発をしつつ、pull-req レビュー用のブランチでレビューできる環境ができました!

$ tmux new -s for_develop
$ tmux new -s for_review

みたいにして tmux で切り替えて管理できるようにするといいかもですね!

ちなみに.gitignoreに指定されているディレクトリ、ファイルはgit-new-workdirでつくったディレクトリには反映されていないのでそこは注意。

まとめ

git-new-workdir便利!!他にもここで紹介されているようにgit-contribには便利なツールがいっぱいあるみたいなので、また試していきたいです。

参考

bundle openでgemのディレクトリを手軽にエディタから確認する

gem のソースって今まで基本 Github から確認していたのですが、実はエディタから手軽に確認できる方法がありました。地味に知らなかったです。

こちらの記事を参考にさせていただきました。

エディタの設定

環境変数EDITORにあらかじめどのエディタを開くのか設定しておく必要がある。自分の場合は vim を使うので、.zshrcに以下のように書いてあります。

export EDITOR=/usr/local/bin/vim

gem のディレクトリを開く

あとはbundlerさえ入っていれば準備 OK.

例えばdeviseを開く時は

bundle open devise

で devise のディレクトリが vim で開ける。

まとめ

最近 Rails の開発が続く日々ですが、こういう地味に知らないことがまだまだ沢山あるので習得していきたいです。

参考

Rails4 + devise + paranoiaで論理削除を考慮したユーザーバリデーションを実現する

Rails でユーザー登録、認証機能を実装する際、deviseを使用することはわりと一般的かと思います。

またユーザーの論理削除を実現するための gem としてはparanoiaが有名かと思います。(Rails3 時代によく使われていた acts_as_paranoid をよりシンプルにしたやつ)

どちらも素晴らしい gem なのですがこれらを同時に使用した際、以下のような問題が発生しました。

  1. devise のvalidatableを使用してUserモデルの validation を実装 (email, password 関連の validation が追加される)。
  2. paranoiaacts_as_paranoidメソッドを呼んで、ユーザーの論理削除をできるようにする。
  3. email: hoge@hoge.comのユーザー hogeemail: fuga@fuga.comのユーザー fuga を用意する。
  4. fuga.destroyで fuga を論理削除。
  5. hoge.update_attributes(email: 'fuga@fuga.com')hoge の email を更新しようとするとユニーク制約で validation エラー発生。

こんな感じで削除済のユーザーと同じ email を登録しようとするとユニーク制約にひっかかってしまって困りました。

今回はこれを通常のユーザーの email ユニーク制約は残しつつ、削除済みユーザーはその対象外となるよう修正していきたいと思います。

とりあえず validatable を外す

まずは deviseのvalidatableを外して、必要なコードを本家からコピーしてくる。

base.class_eval do
  validates_presence_of   :email, if: :email_required?
  #validates_uniqueness_of :email, allow_blank: true, if: :email_changed?
  validates_format_of     :email, with: email_regexp, allow_blank: true, if: :email_changed?

  validates_presence_of     :password, if: :password_required?
  validates_confirmation_of :password, if: :password_required?
  validates_length_of       :password, within: password_length, allow_blank: true
end

必要そうなのはこの辺り。ただvalidates_uniqueness_ofはこのままだとダメなので一旦外す。

DB の index を修正する

devise 導入時の migration で

class DeviseCreateUsers < ActiveRecord::Migration
 中略
  add_index :users, :email, unique: true
end

のようにしていると思うので、その前提で。

これだとdeleted_atに関係なくユニーク制約がついてしまっているので、これを修正するための migration ファイルを作成する。

class UpdateIndexUsersOnEmail < ActiveRecord::Migration
  def up
    remove_index :users, :email
    execute 'CREATE UNIQUE INDEX unique_index_on_users_email ON users(email) WHERE deleted_at IS NULL'
  end

  def down
    execute 'DROP INDEX unique_index_on_users_email'
    add_index :users, :email, unique: true
  end
end

こんな感じでdeleted_atnullの場合のみユニークとする。これで DB 側の修正は OK のはず。

paranoia_uniqueness_validator を使う

次に Model 側の修正。 paranoia_uniqueness_validatorという gem を使用する。これはacts_as_paranoid

class User < ActiveRecord::Base
  validates_as_paranoid
  validates_uniqueness_of_without_deleted :email
end

のようにしていた機能がparanoiaではparanoia_uniqueness_validatorという gem に切り離されたので、これを別途追加する必要があるといった感じ。

こちらの記事とか参考にさせていただきました。

んで、paranoia_uniqueness_validatorでは以下のように validation を追加する。

class User < ActiveRecord::Base
  validates :email, uniqueness_without_deleted: true, allow_blank: true, if: :email_changed?
end

これで期待通りの挙動になるよう修正できた、、はず。

まとめ

gem は便利だけど、思い通りにいかない時は自力で頑張る必要があるということですね。。世知辛い。 もしなにかおかしな所がございましたら、コメント等頂けると嬉しいです!!

参考

Rubyのビット演算子、論理演算子について

Ruby の論理演算子、ビット演算子についてメモ。

論理演算子

一番よく使うやつ。

Ruby論理積論理和ってtruefalseじゃなくてオペランドのどちらかを返す。短絡評価。(片方を評価して結果がわかったら、もう片方を評価せずに結果を返す)

論理積はどちらも真であることを期待するけど、例えば以下のような感じ。

nil && 1 #=> nil

nilを評価した時点でどちらも真である希望はなくなるので、この時点で心折れてnilを返す。

1 && nil #=> nil

とかであれば1を評価して真なので期待に胸をふくらませて次へ。 でもnilなので絶望にひたりながらnilを返す。

論理和の場合はどちらかが真であればいいので

nil || 1 #=> 1
1 || nil #=> 1

となる。

ビット演算子

個人的には普段、あまり使わないかも。

整数の2進表現をビットの列として演算を行う。

ビット積はどちらも 1 の場合のみ 1、それ以外は 0 になるので

1 & 2 #=> 0

となる。(1 は 2 進数で 01、2 は 2 進数で 10)

ビット和はどちらかが 1 なら 1 になるので

1 | 2 #=> 3

Array でビット演算子を使う場合

これ、最近まで知らなかったやつ。地味に使えそう。

Arrayには &|っていうメソッドが定義されてるぽい。Array.instance_methodsやったらちゃんとこいつら出てくる。

&は 2 つの配列を評価して重複する要素を新しい配列に入れて返す。イメージ通り。

[1, 2, 3] & [2, 4, 6] #=> [2]

|は 2 つの配列を合わせて、重複を取り除いてから返す。

[1, 2, 3] | [2, 4, 6] #=> [1, 2, 3, 4, 6]

まとめ

Arrayのビット演算子、積極的に使っていきたい。

参考

PowとtunnelsでRailsのローカル開発環境にSSL導入

仕事で Rails アプリのローカル開発環境に SSL 導入したのでメモ。

pow の導入

powは Rack アプリケーション用のサーバー。仮想的なドメイン名を割り当ててアクセスできるようにしてくれるぽい。

githubreadmeをみて導入。

$ curl get.pow.cx | sh

$ cd ~/.pow
$ ln -s /path/to/myapp

myapp のところが Rails アプリがあるパス。そこのシンボリックリンクを貼っとくだけで ok。

これだけでlocalhost:3000だけでなく、http://myapp.devでもアクセスできるようになる。便利。

tunnels の導入

次にhttps://myapp.devでもアクセスできるようにする。tunnelsという gem を入れればできるらしいので導入。

こちらもreadmeをみて導入。

`gem install tunnels`

$ sudo tunnels

これでhttps://myapp.devにアクセスできました。tunnels はデフォルトで 80→443 ポートの流れを作るので、powで 3000→80、tunnelsで 80→443 という流れですかね。

powを使わなくても/etc/hosts127.0.0.1 myapp.devと書いておいて、sudo tunnels 443 3000でも同じことができるかもしれません。

まとめ

Facebook とか Twitter とか、ソーシャルシェアの機能を試すとき、https じゃないってエラー吐かれたり、余裕っしょって思ってたら本番環境でうまく動かなかったり。 たまにそういうのがあったので今回このような環境を用意しました。

手軽にできるので、もし開発段階から SSL 環境下で検証したい人はぜひに。

参考