コミットコメントに絵文字プレフィックスをつけてみた話

きっかけ

きっかけはこんなツイートを見かけたことから。

「コミットコメントに絵文字!!超可愛いじゃんΣ(゚∀゚ノ)ノキャー」と思って取り入れてみることにしました。

プロジェクトの概要

  • 社内向けシステム構築
  • 開発担当は私1人
  • 悩んだら周りの別プロジェクトをすすめている先輩に相談
  • 1人で実装して1人でリリース
  • たまに先輩がレビューしてくださる

ルール

Wikiに書いた内容のスクリーンショットです。
f:id:maetoo11:20160607094425p:plain:w400

元々は

  • Fix:修正
  • Mod:改善、変更
  • Add:新しい機能やファイルの追加

という文字のプレフィックスをつけていました。

取り入れた様子

f:id:maetoo11:20160607095028p:plain:w400

確かにコミットログが華やかになりました。

しかし、絵文字プレフィックスはやめることに!!

なぜ、絵文字プレフィックスをやめるのか

理由は2点あります。

  • このコミットにはどの絵文字をつければいいんだっけ?と考える時間が発生してしまった。
  • GitHub上だけではなくコンソールでgitのログを確認することもあるので絵文字プレフィックスだと意味がわかりにくい。
    f:id:maetoo11:20160607104011p:plain:w300

1人でざくざく進めたいプロジェクトなので、合わなかったのかもしれません。
GitHubのログを華やかにしたい人のために、FixとかModなどの文字プレフィックスを絵文字に変換して表示してくれるChrome拡張があってもいいのかもしれない、と思いました。

解決済み:cancancanでread権限を設定してもあるページが閲覧できない

2016/5/18に解決しました。
原因と解決方法は下部に記載しています。

やろうとしていること

CanCanCanという権限管理のgemを使用し、権限ごとにModelの操作に制限をつけようとしている。
GitHub - CanCanCommunity/cancancan: Continuation of CanCan, the authorization Gem for Ruby on Rails.

環境

困っていること

あるModelのついて閲覧(read)のみ可能にしたい場合、
readのみ許可では権限がないことになってしまう。
現在は一旦全アクションに対して権限を付与(manage)し、禁止したいアクションをcannotで指定するという形をとっている。

正しく動作しない例:

if user.admin?
  can :manage, :all
elsif user.member?
  can :read, [Hoge, Humu]
end

現在の暫定的な対処:

if user.admin?
  can :manage, :all
elsif user.member?
  can :manage, [Hoge, Humu]
  cannot [:create, :update, :destroy], [Hoge, Humu]
end

上記の正しく動作しない例の状態で、Hogeを閲覧するようなページに遷移すると
権限がないためエラーメッセージが表示される。
「You are not authorized to access this page.」

readを許可するだけでは閲覧は許可されないのかを知りたい。

参考にしたサイト

解決した内容(2016/5/18追記)

原因

該当ページ閲覧時に独自で作成したアクションが呼び出されるようになっていたため。
独自のアクションも許可する必要があった。

解決方法

if user.admin?
  can :manage, :all
elsif user.member?
  can [:read, :original_acthion], [Hoge, Humu]
end

調査は下記ページを参考に行った。
Debugging Abilities · CanCanCommunity/cancancan Wiki · GitHub

デバッグログは上記ページを参考にした。

Rails.logger.debug "Access denied on #{exception.action} #{exception.subject.inspect}"

これで「どのモデル」の「どのアクション」に権限がないのかがわかった。


るっびー先輩、ありがとうございました。

社内勉強会で感動した話(DDD ユビキタス言語再考)

社内勉強会で先輩がお話していた内容に感動しました。

内容の解説ではなく、自分が思ったことを書くので他の人の役には立たないかもしれないです。

また、勉強会は社内クローズドなイベントでしたが、
先輩のスライドはSpeaker Deckというサービスで公開されており、
ブログに書いても良いという許可もご本人にいただいております。

先輩は下記のスライドをもとに発表していました。

speakerdeck.com

どこに感動したのか

ユビキタス言語はチーム全員で合意し創るもの
ユーザーの言語 = ユビキタス言語 というわけではない

という部分に感動した。
感動というか「今ならわかる!」と思った。

なぜ感動したのか(なぜ今ならわかるのか)

多分、似たような話を半年ほど前にも社内勉強会でお話してもらったと思う。
でも、そのときの私は「ユビキタス言語??言葉そんなに大事なの????」という感じだった。

ここ3ヶ月、私は社内向けのシステムを開発している。
(そのシステムは経理担当者や営業担当者がExcelを用いて手動で行っていることをシステム化&一部自動化を目指している。)
ヒアリングを行い、システムの構造を考えていく中で、社内でAと呼んでいた書類が実は一般的にはBという書類とCという書類があってそれを組み合わせたものだということがわかる場面があった。(業務としてもB、Cの書類を発行すべきだった)
担当者から言われた書類の名前をそのまま使うのではなく、どうあるべきかということも担当者やその他関係するメンバーと考えながら認識をすりあわせて行くことができた。
同じ認識になった言葉をつかうと、資料つくりも楽で、認識の齟齬も減った気がする。
その実体験があったから「今ならわかる!」と思えたのだろう。

昔はわからなかったことでも、自分が体験すると理解しやすくなることもあるのかもしれない。


疑問(内容には関係ない可能性あり)

今回の発表内容には関係ないかもしれないが、下記のような疑問がある。

システム化するにあたり、社内オリジナルの名前で英語に直訳できないモデルの名前はどうすればいいのだろう?
(今は無理やり英訳した長い名前をつけている)

railsについて、先輩にもらったアドバイスまとめ(その1)

最近はRuby on Railsで社内システムを作っています。 その中で先輩からもらったアドバイスやレビューで受けた指摘をまとめます。

new()はいらない

hoge = Hoge.new()

hoge = Hoge.new

でよい。
(Rubyは短く楽に書けるときは楽をするのじゃ!)

is_available?のisはいらない

有効かを判定しtrue/falseを返却するようなメソッドの名前は

def is_available?
    # 何らかの処理
end

ではなく

def available?
    # 何らかの処理
end

でよい。
(present?やblank?というメソッドがありますよねー)

※私はこの「?」を疑問形の「?」だと思っていました…(Is this a pen?的な)

破壊的でないメソッドに「!」はいらない

def hoge!
    # 破壊的な処理
end

であり、破壊的でないメソッドに「!」はいらない。
(破壊的な処理を行う場合はprivateメソッドであっても「!」をつけるようにしています)

ある機能追加のために複数のテーブルにカラム追加を行う場合、migrateファイルは分ける

分けたのですが理由が思い出せず…。
※これはもしかしたら1つの機能追加で複数のテーブルに手が入ったことをわかりやすくするために、migrateファイルはわけないほうがよかったのかも?と思いました。

できるだけ短く、意味のある処理ごとにメソッドにする

def calc_hoge
    hoge = 0
    hoge = hoge + (a * b)
    hoge = hoge + (c * d)
end

def calc_hoge
    hoge = 0
    hoge += calc_a_b
    hoge += calc_c_d
end

def calc_a_b
    a * b
end

def calc_c_d
    c * d
end

のようにしたほうがコードが説明的になってわかりやすい。


2016/4/19(火)追記

ステータスコード404でリソースの存在を隠すこともできる

現在作成しているシステムはユーザーにロールを設定しており、ロールによっては閲覧できないリソースがある。
そのリソースを表示するようなページに権限のないユーザーがアクセスした場合、
403が返るとリソースが存在していることが権限のないユーザーにも分かってしまう。
存在自体を隠したいときは404を返す。

詳しくは下記の記事を参照
HTTPステータスコードを適切に選ぶためのフローチャート : 難しく考えるのをやめよう | インフラ・ミドルウェア | POSTD

railsで404のときに表示されるページは public/404.html である。 任意のデザインにしたい場合は404.htmlを編集すればよい。

rspecのテストでカバレッジが計測できるgem、SimpleCovを導入する

テストを書くならカバレッジ計測と行単位で通った・通ってないの確認ができたらいいな、と思っていたら
@tmtms さんより「SimpleCov」を教えていただきました。

GitHub - colszowka/simplecov: Code coverage for Ruby 1.9+ with a powerful configuration library and automatic merging of coverage across test suites

導入手順

Gemfileに「simplecov」を追加

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug'
  gem 'rspec-rails'
  # Test format nyan cat
  gem 'nyan-cat-formatter'
  # テストを自動実行
  gem 'spring-commands-rspec'
  gem 'guard-rspec', require: false
  # カバレッジ取得
  gem "simplecov"
  # モデルにテーブルのカラムをコメントで出力
  gem 'annotate'
end

gemをインストール

$ bundle install --path vendor/bundle --jobs=4
$ # .bundle/configに設定されている場合はbundleでOK

spec/spec_helper.rbにsimplecovのstartを記述

require 'simplecov'

SimpleCov.start 'rails'

RSpec.configure do |config|
  # rspec-expectations config goes here. You can use an alternate
#・・・略・・・

これで準備は完了

使い方

rspecでテストを実行する。

$ bundle exec rspec spec/

するとプロジェクトフォルダ直下に「coverage」というフォルダが作成される。

f:id:maetoo11:20160411194209p:plain

coverageフォルダ配下の「index.html」をブラウザで開く。

f:id:maetoo11:20160411194648p:plain

するとファイルごとのカバレッジ一覧が表示される。

f:id:maetoo11:20160411195350p:plain

ファイル名をクリックすれば、行単位で通った・通っていないが確認できる。

f:id:maetoo11:20160411195827p:plain


導入にあたり参考にしたサイト

rspecでのテストがちょっと楽しくなるgem、nyan-cat-formatterを導入する

テストの待ち時間&結果確認がちょっと楽しくなるgemです。

GitHub - mattsears/nyan-cat-formatter: Nyan Cat inspired RSpec formatter!

導入手順

Gemfileに「nyan-cat-formatter」を追加

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug'
  gem 'rspec-rails'
  # Test format nyan cat
  gem 'nyan-cat-formatter'
end

gemをインストール

$ bundle install --path vendor/bundle --jobs=4
$ # .bundle/configに設定されている場合はbundleでOK

使い方

オプションをつけてrspecを実行!!

$ bundle exec rspec --format NyanCatFormatter spec/

すると… f:id:maetoo11:20160407155537p:plain

※テスト実行中はNyan Catが走ります

テストが落ちると… f:id:maetoo11:20160407155851p:plain

とりあえずユーザー管理と認証を実装したいのでdeviseを使う

自力で実装する心の余裕が消えたのでdeviseを使うことにしました。
もうすでにあるものはガンガン使おう!そうしよう。

インストールや設定手順は下記リンクを参照しました。

手順

Gemfileにdeviseを追加する。

gem 'devise'

bundle installを行う。
(ここではbundlerの設定をそのまま使用したいのでbundleコマンドを実行している)

$ bundle
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies...
Using rake 10.5.0
・・・略・・・
Using rack-test 0.6.3
Installing orm_adapter 0.5.0
Installing warden 1.2.6
Installing bcrypt 3.1.11 with native extensions
Using mail 2.6.3
・・・略・・・
Using web-console 2.3.0
Installing responders 2.1.1
Installing devise 3.5.6
Bundle complete! 16 Gemfile dependencies, 72 gems now installed.
Bundled gems are installed into ./vendor/bundle.

devise関連ファイルのをrailsコマンドで生成する。

$ bundle exec rails generate devise:install
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:

       config.assets.initialize_on_precompile = false

     On config/application.rb forcing your application to not access the DB
     or load models when precompiling your assets.

  5. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===============================================================================

環境を設定する。
config/environments/development.rb に下記を追記する。

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

devise用のUserモデルを作成する。

$ bundle exec rails g devise User
      invoke  active_record
      create    db/migrate/20160321071935_devise_create_users.rb
      create    app/models/user.rb
      invoke    rspec
      create      spec/models/user_spec.rb
      insert    app/models/user.rb
       route  devise_for :users

Userテーブルを追加するのでmigrateする。

$ bundle exec rake db:migrate:reset
== 20160321071935 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0166s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0333s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0259s
== 20160321071935 DeviseCreateUsers: migrated (0.0760s) =======================

deviseが出力するメッセージの表示場所を設定する。
(ここでは app/views/layouts/application.html.erb に設定)
ついでにナビゲーションバーにログインしていない場合はログイン、ログイン済みの場合はログアウトというリンクを表示する。

<body>
  <header>
    <div class="">
      <% if user_signed_in? %>
        <div>
          Logged in as <strong><%= current_user.email %></strong>.
          <%= link_to "ログアウト", destroy_user_session_path, method: :delete %>
        </div>
      <% else %>
        <div>
          <%= link_to "ログイン", new_user_session_path %>
        </div>
      <% end %>

    </div>
  </header>

  <div>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </div>

</body>

undefined method `devise_for'というエラーが出た。
f:id:maetoo11:20160321175102p:plain
→一度rails serverを再起動しないといけないらしい。
undefined method `devise_for' in rails - Stack Overflow

正しく動けば以下のようなログイン画面が表示されるはず。
f:id:maetoo11:20160321175236p:plain

その他

ログインしていないユーザーはログイン画面にリダイレクトするよう設定したかったので下記を参考に実装。
devise + omniauth-facebookでリクエストURLにリダイレクトする - yasuoza diary

初期ユーザーの追加をする。
Devise に初期ユーザを追加 - Ruby and Rails


Ruby on Rails 4 アプリケーションプログラミング

Ruby on Rails 4 アプリケーションプログラミング