読者です 読者をやめる 読者になる 読者になる

SideCI TechBlog

SideCIを作っているアクトキャットのエンジニアによる技術ブログです。

モデルがなくてもいいじゃない!deviseを使わないでユーザ認証をさくっと実現する

こんにちは!シン・ゴジラをあと3回くらい見たい @sweep3092 です。

f:id:sideci-dev:20160923132553p:plain

Railsでユーザ認証といえばもはやセットのようになっている devise + omniauth という構成が一般的ですが、 今回はありそうでなかなか情報が見つからない、Railsでモデルを持たずにさくっとユーザ認証をする話をしようと思います。

モデルを持たずにユーザ認証を実装するのは、なんと言っても既存のユーザ認証の仕組みとバッティングしにくいのがメリットです。 deviseを使うといろいろとイイカンジに設定してくれるのでとても便利ですが、別の管理のユーザ認証の仕組みを追加しようとしたりすると嵌まりがちです。 ここで原点に立ち返って、「devise使わないでもいいのでは?」となり、「そもそもモデル要らないのでは」となったのが本記事を書いたきっかけになります。

ユーザ認証の仕組みだけをさくっと提供するのが目的なので、認証したユーザを別のモデルとリレーションさせたりするのにはあまり向きませんが、 社内OAuthアカウントだけ認証できればいいから出来るだけ簡単に作りたい、といった場合にはモデルはなくても十分機能する場合も多いのではないでしょうか。

本記事では、omniauthのroutesやAPIキーの設定などの基本的な設定を済ませた前提で、モデルを持たないユーザ認証の仕組みを実現するControllerの書き方をご紹介いたします。

目的

  • deviseも使わずモデルも持たずにomniauthでユーザ認証の仕組みを作る
  • 社内アカウントのみ許可する

方法

今回はすでに User というモデルが存在すると仮定して、 Staff という別のユーザの概念をアプリケーションに持ち込むことを想定し、 Staff 専用のApplicationController, SessionsControllerを作ります。 このとき User とバッティングしないように、namespaceを明示的に分けます。

SessionsController

omniauthのcallbackが帰ってくるcreateアクションでは、セッションに使いそうなユーザ情報を雑に入れておきます。 また、このとき「社内アカウントであるか」をチェックします。 今回はメールアドレスが独自ドメインのものかを確かめるようにしていますが、ここは用途に合わせて変更して頂くのが良いかと思います。

ApplicationController側でセッションをみてログイン済みかどうかを確認するので、ログアウトの際には reset_session すればOKです。

class Staff::SessionsController < Staff::ApplicationController
  skip_action_callback :authenticate_staff!
  def login
  end

  def create
    auth = request.env['omniauth.auth']

    # 社内アカウントじゃなければログイン画面に戻してエラー表示
    unless auth.info.email.end_with? '@mycompany.co.jp'
      redirect_to staff_sessions_login_path, flash: {error: '社内アカウントのみ使用できます'}
    end

    # モデルなどに格納せず、sessionに使いそうなユーザ情報を雑に入れる
    session[:staff_uid] = auth.uid
    session[:staff_name] = auth.info.name
    session[:staff_email] = auth.info.email

    redirect_to staff_path
  end

  def destroy
    reset_session
    redirect_to staff_sessions_login_path
  end

  def failure
    redirect_to staff_sessions_login_path
  end
end

ApplicationController

ここでは、 Staff が認証済みであるかどうかを確認するメソッドを定義します。情報が欠けていたら reset_session をしてログイン画面にリダイレクトします。 また、ログイン中の Staff の情報を取得するヘルパメソッドを定義します。deviseで使える current_user などと同じようなイメージです。 同様に、 staff_signed_in? などのヘルパーメソッドも用意しておくと使い勝手が良いかと思います。

class Staff::ApplicationController < ActionController::Base
  helper_method :current_staff
  helper_method :staff_signed_in?
  before_action :authenticate_staff!, except: [:login]
  skip_action_callback :authenticate_staff!

  private

  def authenticate_staff!
    if session[:staff_uid].blank? || session[:staff_email].blank? || session[:staff_name].blank?
      reset_session
      redirect_to staff_sessions_login_path, flash: {error: 'ログインしてください'}
    end
  end

  def current_staff
    return nil if session[:staff_uid].blank? || session[:staff_email].blank? || session[:staff_name].blank?
    {
        uid: session[:staff_uid],
        email: session[:staff_email],
        name: session[:staff_name],
    }
  end

  def staff_signed_in?
    current_staff.present?
  end
end

使い方

<p>ようこそ <%= current_staff[:name] %> さん</p>

とか

<% if staff_signed_in? %>
 <%= link_to 'logout', staff_sessions_destroy_path %>
<% end %>

さいごに

やってみれば何の変哲も無い当たり前の超絶簡単なユーザ認証ですが、omniauthってどうやって使うんだっけ、と調べているとどうしてもdeviseを使うように流されてしまいがちのように思います。 ですが用途によってはRailsとは言ってもdeviseに頼らず、モデルに縛られずに原点に立ち返ってセッションのみでさくっとユーザ認証を済ませてしまうのもいいのではないでしょうか。

現在アクトキャットでは一緒に働いて頂けるメンバーを募集しています。 Webエンジニアの方、インフラエンジニアの方、Webデザイナー、マーケターの方を積極採用中です! 興味がある方はぜひWantedlyからご応募ください!

https://www.wantedly.com/companies/actcat/projects

RuboCop 0.43.0 の CHANGELOG を読む

こんにちは、RuboCop大好き!Pockeです。

先日、RuboCopのバージョン0.43.0がリリースされました。

Release RuboCop 0.43 · bbatsov/rubocop

このリリースには、筆者を始めとするSideCIのメンバーによるPull Requestも11個含まれています。 今日はそのCHANGELOGから、気になる新機能を見ていきましょう。

新規Cop追加

Copとは、RuboCopにおいてひとつのルールを指す言葉です。例えば、「インデントが正しいかチェックする」「非推奨メソッドを使っていないかチェックする」などが1つのCopの単位になります。 この章では、0.43.0で新たに追加されたCopをひとつずつ紹介します。

Style/DocumentationMethod

このCopはPublicメソッドに対してドキュメントコメントを書くことを促します。

解説

class MyClass
  # Method1 does something.
  def method1
    # ...
  end

  def method2
    # ...
  end


  private

  def method3
    # ...
  end
end

例えば上記のようなClass定義をこのCopで検査した場合、def method2の部分に下記のような指摘が行われます。

test.rb:7:3: C: Missing method documentation comment.
  def method2 ...
  ^^^^^^^^^^^

def method1ではドキュメントコメントが書かれているため、またdef method3ではプライベートメソッドを定義しているため、指摘は発生しません。

まとめ

長く保守していくコードでは、ドキュメントコメントの有無がメンテナンスを行う上で重要となります。
コーディング規約としてコメントを書くことを強制したい場合、このCopを有効活用することが出来るでしょう。

なお、コメントを書く必要が薄いメソッドも多いためか、このCopはデフォルトでは無効になっています。 そのため、このCopを使用したい場合は.rubocop.ymlなどで明示的に有効にする必要があります。

Style/SafeNavigation

このCopはSafe navigation operatorが使用できる場合、それを使用することを促します。

Safe navigation operatorは、Ruby 2.3で新たに追加された演算子です。 foo&.barの様に使用します。これはfoo.nil? ? nil : foo.barのように動作します。

参考: サンプルコードでわかる!Ruby 2.3の主な新機能 - Qiita

解説

if foo
  foo.bar
end

foo.bar if foo

foo && foo.bar

上記のような文は、全てfoo&.barで代替することが可能です。 そのため、上記コードに対して検査を行うと、以下のような指摘が行われます。

test.rb:1:1: C: Use safe navigation (&.) instead of checking if an object exists before calling the method.
if foo ...
^^^^^^
test.rb:5:1: C: Use safe navigation (&.) instead of checking if an object exists before calling the method.
foo.bar if foo
^^^^^^^^^^^^^^
test.rb:7:1: C: Use safe navigation (&.) instead of checking if an object exists before calling the method.
foo && foo.bar
^^^^^^^^^^^^^^

まとめ

Safe navigation operator を使用することでコードをシンプルに保つことが可能です。
導入してみてはいかがでしょうか。

なおSafe navigation operatorはRuby2.3から追加された演算子であるため、このCopを動作させるには.rubocop.ymlで明示的にRubyのバージョンを指定する必要があります。
以下のコードを.rubocop.ymlに追記して下さい。

AllCops:
  TargetRubyVersion: 2.3

Rails/SafeNavigation

このCopもStyle/SafeNavigationと同様、Safe navigation operatorが使用できる場合にそれを使用することを促します。 Style/SafeNavigationと異なる点は、ActiveSupportで追加されるtry!メソッドを対象にすることです。

解説

foo.try!(:bar)

例えば、上記のコードはfoo&.barと同等です。そのため、上記のコードを検査すると以下の指摘が行われます。

test.rb:1:1: C: Use safe navigation (&.) instead of try!.
foo.try!(:bar)
^^^^^^^^^^^^^^

まとめ

ActiveSupportが提供する拡張に依存しないコードを書くことが出来るため、積極的にSafe navigation operatorを使うように矯正できるこのCopは有用でしょう。

なお、このCopを有効にするには以下のコードを.rubocop.ymlに追記する必要があります。

AllCops:
  TargetRubyVersion: 2.3

Rails:
  Enabled: true

Rails/NotNullColumn

Railsアプリケーションのマイグレーションファイル内で、NOT NULL制約がついておりデフォルト値がついていないカラムの追加を検出します。

解説

class AddNotNullColumn < ActiveRecord::Migration[5.0]
  def change
    add_column :users, :name, :string, null: false
  end
end

上記のようなマイグレーションを実行すると、(使用しているRDBMSにもよりますが)多くの場合エラーが発生してマイグレーションが失敗してしまいます。
またMySQLを使用している場合にはエラーは出ないものの、既存のレコードのnameカラムに対してはMySQLが勝手にデフォルト値を設定します。

そのため、このCopは上記のコードに対して下記の指摘を行います。

db/migrate/test.rb:3:40: C: Do not add a NOT NULL column without a default value
    add_column :users, :name, :string, null: false
                                       ^^^^^^^^^^^

この指摘を回避するには、null: false, default: ''のようにデフォルト値を指定する必要があります。

まとめ

開発時と運用時で異なるRDBMSを使用していたり複数のRDBMSのサポートを行っている場合、このCopは問題の早期発見に役立つでしょう。

なお、このCopを有効にするには以下のコードを.rubocop.ymlに追記する必要があります。

Rails:
  Enabled: true

Style/VariableNumber

このCopは、変数名に数字を含める際のスタイルを統一します。

解説

変数名に数字を含める場合、以下のような3通りのケースが考えられます。

# 変数名にそのまま数字を続ける
var1 = 1

# 変数名と数字の間にアンダースコアを入れる
var_1 = 1

# 数字をそもそも使わない
var_one = 1

このCopを使用することで、この3つのスタイルのうちどれかに統一することが可能です。 それぞれ.rubocop.ymlに以下のコードを追記します。

# var1 に統一する場合
Style/VariableNumber:
  EnforcedStyle: normalcase

# var_1 に統一する場合
Style/VariableNumber:
  EnforcedStyle: snake_case

# var_one の様に数字を含ませないよう統一する場合
Style/VariableNumber:
  EnforcedStyle: non_integer

まとめ

プロジェクトで変数の命名規則が決まっている場合、このCopを有効活用することが出来るでしょう。

特に命名規則が決まっていない場合、以下のコードを.rubocop.ymlに追記することでこのCopを無効にすることが可能です。

Style/VariableNumber:
  Enabled: false

Performance/SortWithBlock

このCopは、パフォーマンス上の観点から不要なsortメソッドの呼び出しをsort_byメソッドに置き換えます。

解説

Rubyには、ソートを行う為のメソッドがsortsort_byの2つ定義されています。

配列の中身をStringに変換した上で辞書式順序でソートしたい場合、sortメソッドでは以下のように書きます。

array.sort{|a, b| a.to_s <=> b.to_s}

しかし、この書き方では後述するsort_byメソッドより低速になってしまいます。 sortメソッドは比較を行う度にブロックを呼び出すため、比較の回数だけto_sが呼ばれてしまいます。

sort_byを使用すると、この点を解消することが可能です。

array.sort_by(&:to_s)

sort_byでは全ての要素に1度ずつしかto_sを呼び出さないため、このケースではsortを使用するよりも高速にソートを行うことが可能となります。

このCopを使用して最初に例にあげたコードを検査すると、以下のような指摘を行います。

test.rb:1:7: C: Use sort_by(&:to_s) instead of sort { |a, b| a.to_s <=> b.to_s }.
array.sort{|a, b| a.to_s <=> b.to_s}
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

まとめ

このCopを使用することで、パフォーマンス上の問題となりうる点を自動的に検出することが可能です。

また、このCopはAuto Correct機能に対応しているため、-aオプションを付与してRuboCopを実行することで対象のコードを自動で修正することが可能です。

Lint/UnifiedInteger

このCopは、Fixnum, Bignumクラスを参照している箇所を検出します。

解説

Ruby 2.4 では、Fixnum, BignumクラスはIntegerクラスに統合される予定です。

参考: サンプルコードでわかる!Ruby 2.4の新機能と変更点 - Qiita

Ruby 2.4からはFixnum, Bignumクラスは両者ともIntegerクラスへの参照となります。 そのため、Fixnumがコード中に書かれている場合は見た目と挙動が異なり、わかりづらいコードとなってしまいます。

このCopはそのような状態を防止するため、Fixnum,Bignumクラスの使用を指摘します。 例えば、以下のコードに対して以下の指摘を行います。

a.is_a? Fixnum
a.is_a? Bignum
a.is_a? Integer
test.rb:1:9: W: Use Integer instead of Fixnum.
a.is_a? Fixnum
        ^^^^^^
test.rb:2:9: W: Use Integer instead of Bignum.
a.is_a? Bignum
        ^^^^^^

まとめ

このCopを使用することで、上記のような紛らわしいコードを検出することが可能です。

また、このCopはRuby 2.4未満を使用している場合でも有効となっています。 Ruby2.4への移行を考えた際にこのCopが有効に働くこと、そもそもFixnumBignumを使用するケースは少なくIntegerの間違いである可能性が高いこと、が理由です。

その他

この章では、新規Cop追加以外の新機能を見ていきます。

HTMLフォーマッタの出力に目次がつくようになりました

rubocop --format html > index.htmlの様にRuboCopを実行すると、RuboCopの結果をHTMLとして出力することが可能です。 今回のリリースでは、この出力に目次がつくようになりました。

f:id:sideci:20160920132901p:plain

筆者はあまりHTMLフォーマッタを使用しないのですが、このフォーマッタをよく使用するユーザーにとっては便利な機能かもしれません。

まとめ

この記事は以上になりますが、RuboCop 0.43.0ではこの他にも多くの機能追加、バグ修正が行われています。 より詳しい変更を知りたい方は、リリースノートをご覧ください。

Release RuboCop 0.43 · bbatsov/rubocop

また、SideCIでは今すぐRuboCop 0.43.0を利用することが可能です。是非お試し下さい!

PackerのAMI手動管理を卒業するプラグインを作ってみた

こんにちは、家から捕まえられるポケモンだけを捕まえて僕のポケモンGoは終了しました。@wata727です。

f:id:sideci-dev:20160817154928p:plain

弊社ではインフラ自動化の一環として、AMIの作成にPackerを利用しています。PackerはAMIを作るまでは自動化してくれるものの、作成されたAMIは残り続け、使わなくなった古いAMIは手動で削除しなくてはいけません。
この点に関して、公式*1では、

Packer only builds images. It does not attempt to manage them in any way. After they're built, it is up to you to launch or destroy them as you see fit. If you want to store and namespace images for easy reference, you can use Atlas by HashiCorp.

と述べており、Atlasを使ってくれという立場です。とはいえ、そこまで大げさな話でもないし、毎回手動で削除しないといけないのは面倒臭い、そうだ、Packerにはプラグインの仕組みがあるじゃないか、プラグインを作ろう、となったのが今回の経緯です。

Packerプラグインの仕組み

PackerはGo言語で作られており、本体は単独で実行可能なバイナリとして提供されています。 Packerのプラグインも同様にGo言語で作成し、単独のバイナリとして提供されます。内部的には、RPCを使ってPacker本体とやり取りをすることで、独自の処理を追加することができます。 詳しくは公式のドキュメントに書いてありますが、大まかに言うと以下のような処理をmainに書いて、自作プラグインの処理を登録します。

package main

import (
    "github.com/mitchellh/packer/packer/plugin"
    "github.com/yourname/packer-type-name
)

func main() {
    server, err := plugin.Server()
    if err != nil {
        panic(err)
    }

    server.RegisterPostProcessor(new(yourplugin.PostProcessor))
    server.Serve()
}

github.com/mitchellh/packer/packer/pluginがPackerのプラグインを作る上で必要なものをすべて持っているので、基本的にはこれをimportすれば動作させることができます。 後は追加したい処理をプラグインのインターフェイスを満たすようにゴリゴリ実装します。プラグインの種類はいろいろありますが、今回はAMIを作成したタイミングで、古いAMIを削除できれば良いので、最後に処理を挟むpost-processorプラグインを選択しました。

作ったもの

で、完成したものがこちらになります。

名前が異常に長いですが、packer-post-processorまでは命名規則なのと、他のpost-processor、amazon-importなどにあわせた結果、こんな名前になりました。もうちょっといい名前があったかもしれません...

インストール

ビルド済みのバイナリをダウンロードしてきて~/.packer.d/pluginsに配置するだけで動作します。 最初はpluginsディレクトリが無いこともあるので、その場合には作ってください。

$ wget https://github.com/wata727/packer-post-processor-amazon-ami-management/releases/download/v0.1.0/packer-post-processor-amazon-ami-management_linux_amd64.zip
$ unzip packer-post-processor-amazon-ami-management_linux_amd64.zip
$ mv dist/linux_amd64/packer-post-processor-amazon-ami-management ~/.packer.d/plugins

使い方

post-processorとしてamazon-ami-managementを以下のように指定します。

{
  "builders": [{
    "type": "amazon-ebs",
    "region": "us-east-1",
    "source_ami": "ami-6869aa05",
    "instance_type": "t2.micro",
    "ssh_username": "ec2-user",
    "ssh_pty": "true",
    "ami_name": "packer-example {{timestamp}}",
    "tags": {
        "Amazon_AMI_Management_Identifier": "packer-example"
    }
  }],
  "provisioners":[{
    "type": "shell",
    "inline": [
      "echo 'running...'"
    ]
  }],
  "post-processors":[{
    "type": "amazon-ami-management",
    "region": "us-east-1",
    "identifier": "packer-example",
    "keep_releases": "3"
  }]
}

AMIを作成するときにAmazon_AMI_Management_Identifierをキーに、任意の値のタグを設定しておけば、そのタグの値を指定することで世代管理の対象とすることができます。何世代まで維持するかどうかはkeep_releasesで指定できます。 これでいちいち古いAMIがたまった時点で定期的に削除する必要が無くなって、AWSの料金もきっちり節約できます、うれしいですね!

まとめ

普段、実務ではRubyを使うことが多いのですが、Goでコードを書いていて、特にAWSの通信まわりのモックを書くのに結構苦労しました... 現状はgomockを使ってSDKのモックを自動生成してそれを使っているのですが、もっと良い方法があればぜひ知りたいです。

Packerのプラグイン機構はまだ試験的なものとのことですが、短いコードでかなりいろいろな拡張ができるので、ぜひ便利プラグインを作って配布してください!

参考

突撃!どんな環境で開発していますか? SideCIメンバー編

こんにちは。 Atom大好き! @sumyapp です。SideCIのプロダクトオーナー的なことをしております。 この記事はこのテックブログの記念すべき10回目です。

しかしながら、最近まったく開発をしていない私で御座いますので、今回はインタビュー形式で社内の開発環境を取材していきたいと思います。
取材途中で全員分取材すると分量が大変そうなことに気づいたので、今回は4名分だけ。

セパレートキーボード始めました @sumyapp

インタビュー形式といいつつ、まずは私の環境から公開です!

f:id:sideci-dev:20160805150928j:plain

最近の業務内容と得意領域を教えて下さい

最近の業務内容は開発以外の全てですね。プロダクトのワイヤフレームを作ったり、ヒアリングにお伺いしたり。その他、オフィス(物件)を探したりとか、ほんとに何でもやっています。

得意領域は以前はネイティブアプリ(Obj-C, Android Java)とRailsといった感じだったのですが、今はプロダクトのためにやるべきことをやる、ということにフォーカスしていますね。

開発環境(物理)について教えて下さい

11inchのMacBook Air, 27inchの外付けディスプレイ、iPad mini Retina(Duet)を使ったトリプルディスプレイ構成です。キーボードはKinesis Freestyle2 for Macを使っています。

セパレートキーボードは先週買ったばっかりで、まだポテンシャルを十分引き出せていないなと思います。Ergodoxなども検討したのですが、USキーボード自体初めてで、一般的な配列のこれにしました。

f:id:sideci-dev:20160805151242j:plain

開発環境(ソフトウェア)について教えて下さい

立ち上がりの早いVimとAtomを使っています。1ファイルだけ修正する場合はVim、プロジェクト全体のソースを見る場合にはAtomといった使い分けです。

f:id:sideci-dev:20160805151010p:plain

1つだけ何かをお勧めするとしたら、何をおすすめしますか?

一番シンプルなところで、クリップボードの拡張アプリの「Clipy」はお勧めです! https://clipy-app.com/

最後に一言お願いします

キーボードを買い換えてから以前まで「当たり前」と感じていた肩こりが、セパレートではないキーボードを使うと肩こりが気になる、ぐらいになった気がします。 ぜひ皆様もこの夏、セパレートキーボードデビューしてみませんか?


エディタはRubyMine、好きなサービスはAWS @wata727

最近Sublime TextからRubyMineに鞍替えした @wata727 のデスクに訪問してみます。

f:id:sideci-dev:20160805151110j:plain

最近の業務内容と得意領域を教えて下さい

新機能の開発とインフラ関係を見ています。得意領域はAWSとかクラウド系とかですかね。 ※彼はAWSソリューションアーキテクトを有しているAWSのスペシャリストです。

開発環境(物理)について教えて下さい

MacBook Air 13inchと27inchのデュアルディスプレイと至って通常の開発環境です。拘りはないですね。拘りがないのが拘り

f:id:sideci-dev:20160805151257j:plain

開発環境(ソフトウェア)について教えて下さい

エディタはがっつり開発するときはRubyMineです。軽いものはSublimeだったりvimだったりします。

Terraformの設定ファイルなどインフラ周りのファイルを変更するときにはSublimeですね。軽く動くのでとても良いです。デバッグとかになるとRubyMineがやはり必要になるけれど、軽く弄りたいときはやっぱりSublimeです。

ターミナルはiTerm2, shellはzsh。たぶんそんなに面白いことはしていないと思います。わりと普通な感じです。

f:id:sideci-dev:20160805151310p:plain f:id:sideci-dev:20160805151343p:plain

1つだけ何かをお勧めするとしたら、何をおすすめしますか?

envchainが結構好きです。AWSのcredentialみたいなセキュリティ情報をexportでベタ書きせずに、Macのキーチェーンに入れて扱えるのがいいところですね。

envchain <namespace> を頭につけてコマンドを叩くと、設定した環境変数が引っ張ってこれるので、namespaceを分ければ、環境の切り替えもスムーズにできて重宝しています。

最後に一言お願いします

最後に一言ってすっごい難しいんですけど(私の適当過ぎるフリにちょっとおこ)


RubyMine大好き!でおなじみ @Vexus2

今度はJetBrains教の @Vexus2 先生のデスクに訪問してみます。

f:id:sideci-dev:20160805151143j:plain

最近の業務内容と得意領域を教えて下さい

開発全般。開発全部みたいな感じですかね。 得意領域は継続的インテグレーション周りの整備や開発フローの構築など、チーム寄りなエンジニアかなーと自称しています。

開発環境(物理)について教えて下さい

40インチUltraHD、MacBook Airのデュアルディスプレイです。 ターミナルを別画面にしたいのでトリプルディスプレイにしたいなと思っているんですが、今使っているディスプレイが解像度が大きい故に、表示が遅いので、トリプルは厳しいかなーと思っています。 モニタを画面分割しているし、バーチャルデスクトップを沢山使っていて、画面移動しまくるので、流石に少しカクカクしますね。

f:id:sideci-dev:20160805151519j:plain

開発環境(ソフトウェア)について教えて下さい

エディタはRubyMine、ターミナルはiTerm2 + tmux、shellはzshです。

f:id:sideci-dev:20160805151310p:plain

1つだけ何かをお勧めするとしたら、何をおすすめしますか?

RubyMine以外だとTotalSpaceですね。 TotalSpaceなしでみんなが生きていける理由が知りたいです。というぐらいにお勧めです。

最後に一言お願いします

RubyMine大好きって言わされている感があるのでノーコメントで


HHKB BTを操るSublimer @sweep3092

HHKBとgitを巧に使いこなすSublimer @sweep3092 さんの机にやってきました。
彼はmixi主催の「git challenge」の優勝者です。

Bluetooth接続のHHKBがシュッと決まってます。わりと一般的そうな構成ですが、果たしてその中身は。(ところでSublime text利用者をSublimerって勝手に呼んじゃったのですが呼び方正しいでしょうか…?)

f:id:sideci-dev:20160805151155j:plain

最近の業務内容と得意領域を教えて下さい

そうですね、基本的にはフロントエンドを触る方が多いです。 得意領域はユーザの行動を考える、フロント側からサービスを考えていく、というのが得意です。

情報セキュリティスペシャリストをこの間取得しました。本番サーバでのログ出力などについても、セキュアな情報が一切含まれないように情報のマスクなどは気をつけていますね。

開発環境(物理)について教えて下さい

MacBook Pro Retina 13inch、27inchのディスプレイ、HHKB、magic trackpadです。
これは自宅や研究室のデスクなどでも同じです。
全部揃えていて、全部HHKBで、全部magic trackpadです。

f:id:sideci-dev:20160805151535j:plain

開発環境(ソフトウェア)について教えて下さい

開発はRubyMineを使っていますね。

RubyMineだと単純なタイプミスなどもすぐ気づけますし、使われてない変数なども出てきます。バグが出たときなども見当を付けやすいですね。

Sublime Textの方がサクサク動くのでそこがSublimeの方が良い点ですね。

f:id:sideci-dev:20160805151310p:plain f:id:sideci-dev:20160805151343p:plain

1つだけ何かをお勧めするとしたら、何をおすすめしますか?

ハードウェアだとHHKBですね。
ソフトウェアだとソフト的なカスタマイズをしないでおくのがすきなので、あえてほとんどカスタマイズしないで使うというのが多いですね。

会社や研究室やサーバルームなど色々な場所で色々なコンピュータを触るので、あえてカスタマイズはしないですね。
(※SideCIはAWSを主に使っており、ここでいうサーバルームとは彼が所属する大学の研究室のサーバルームです)

最後に一言お願いします

@Vexus2 さんだとRubyMine最高とか言うんでしょうね。私は「最後に一言」に適切な言葉をひねり出せなかったです。「HHKB最高」とかそういう感じで。

f:id:sideci-dev:20160805151554j:plain


その他 / 全員共通

前傾チルト機能付きオフィスチェア

f:id:sideci-dev:20160805174516p:plain http://www.haworth.com/products/seating/desk-chairs/zody

ずっと座って仕事をするので椅子は大切!ということで、弊社では前傾チルト機能、4Dアーム、ランバーサポートなどフル機能を備えたヘイワース社のゾディチェアを会社全体で使っています。 (移転直後購入が間に合わず、慌てて買った『日本の「もてなしの心」を体現したチェア』と名高いイトーキ スピーナチェアも2脚だけあるのは秘密です。)

おわりに

社内の標準構成はMBAもしくはMBPと27インチディスプレイなのですが、40インチにトライしてみたり、エディタを変えてみたり、健康志向に目覚めてみたり。開発生産性のためとあらばまずはトライしてみているメンバーが多い印象です。
ぜひ皆様も気に入った物がこの中にあればぜひ試してみて下さい。

もし会社全体の環境や開発プロセスなどについても知りたいと思って頂けた方はコーポレートサイトをご覧頂ければ幸いです。
http://www.actcat.co.jp/jobs

独断と偏見で選んだ「開発効率向上」のための有料Macアプリ6選

こんにちは!RubyMine大好き!vexus2です。 自分は「開発効率の向上が大好き、効率化のためなら生産性が落ちても良い(健康のためなら死んでもいい的な)」をモットーにしているので、こと開発マシン内の最適化にはこだわることが多いです。

最近メインモニタを40インチにしたり開発環境周りを多少変えてみたので、私が使っている主に開発周りでのMacアプリをいくつか紹介してみます。

なお、エディタ系とかKarabinerとか、Alfredみたいな定番のいわゆる「おすすめアプリまとめ」の類はあえて省いています。

TotalSpaces2($11.99)

totalspaces.binaryage.com

f:id:sideci-dev:20160719122047p:plain

仮想デスクトップを構築するソフトウェアです。OSX Mavericks以降はMissionControlでも似たようなことが出来ますが、MissionControlだと横一列にデスクトップが並ぶのに対して、TotalSpaces2では縦横に構築できるのでデスクトップ間の移動が非常に高速です。

また、各アプリごとにどの仮想デスクトップに表示されるかを固定することができるので、例えば

  • 仮想デスクトップ1 -> 開発スペース(エディタ、ターミナル系)
  • 仮想デスクトップ2 -> ブラウザスペース(Chrome, Safari他)
  • 仮想デスクトップ3 -> マルチメディア系スペース(itunes他)
  • サブモニタ -> Slack

みたいにデスクトップごとに役割を固定化させることができるのでどこのデスクトップでなんのアプリを開いているのかというごちゃごちゃ感が少なくなることで脳内のスイッチングコストが少なく、アプリがいっぱい起動している状態でも低ストレスかつ高速にアプリ間を移動できます。

また、デスクトップ間移動時のトランジション(エフェクト)を無効にすることで移動が更に高速になって便利です。

デスクトップ間移動のショートカットはトラックパッドに割り当てられていますが、上下左右を縦横無尽に動きまわるためにキーボードにも割り当てておくことを個人的におすすめします。

BetterSnapTool(360円)

BetterSnapTool を Mac App Store で

f:id:sideci-dev:20160719145118p:plain

ウィンドウのリサイズやドラッグ周りを拡張してくれるツールです。Windows7的な感じで画面端にウィンドウをドラッグした時に吸着しながら拡大とかも設定できます。(個人的にはドラッグでウィンドウを移動することはないので全く使ってません)

そこそこ大きめのモニタを使っていると画面内でアプリやエディタを2分割、3分割、4分割・・・としたくなると思います。

このツールでは今開いているアプリを画面の右半分で開くなど、右の1/3で開くなど縦に2分割、3分割がショートカット上でできるようになります。

また、デュアル/トリプルモニタを使っていると「今開いているアプリをサブモニタに移動したい」ケースって多々あると思うんですが、このツールなら「今開いているアプリを次のモニタに送って最大化」とかができるのでめちゃくちゃ快適です。

トラックパッドを使ってアプリをリサイズしたり移動していた頃が懐かしく思えるくらいに快適なので、画面を分割したりとかサブモニタ頻繁に使う方にはぜひオススメしたいツールです。

Jitouch2($7.99)

f:id:sideci-dev:20160720104611p:plain

jitouch 2 - Multi-Touch Extension for MacBook Multi-Touch Trackpad & Magic Mouse

トラックパッドでの操作を強力に拡張してくれるツールです。

類似にBetterTouchTool(BTT)がありますが、こちらも最近有料化しました。Jitouch2とBTTのどちらを使うかは割と好みの問題かなあと思いつつ、文字ジェスチャにアクションが割り当てられるのでJitouch2を使っています。

OSX El Capitanになってからたまにコマンドが認識されなくて、Jitouch2の再起動が必要だったりすることが増えたのでちょっとめんどくさいなあと思うことはたまにありますが、それでもやはり便利です。

Duet Display(2300円)

f:id:sideci-dev:20160719141849p:plain

www.duetdisplay.com

Macに接続してiPadをデュアルモニタにしてくれるツールです。LPには「生産性が最大48%向上します」と書いてあるのにスクリーンショットには「生産性が2倍になります」と謳っていたり、サイトの日本語が色々怪しかったりといったこともありますが、ツールとしてはとても便利です。

割とお高いお値段する割には動作が安定しないことが多いので、メインモニタがある状態からのトリプルモニタ用途というよりは、自席以外での開発でのサブモニタとしてブラウザとかSlackとかを表示しておく用途向けで個人的に重宝しています。今後、安定性が向上してくれることを切に祈ります。

MenubarClock(120円)

Menubar Clock | NagisaWorks

f:id:sideci-dev:20160719142820p:plain

最大3つまでのタイムゾーンでの時計を同時に表示できるツールです。弊社でも日本以外のリモートメンバーも増えたということもあり、「現地時間だと何時だっけ・・・」というのをサクッと把握できるのでべんりです。

Yoink(840円)

Yoink - ドラッグ & ドロップを快適なものに を Mac App Store で

D&Dなどでのファイル移動時にテンポラリ領域を作ってくれるツールです。昔はDragonDropというツールがあったんですがひっそりとApp Store上から消えてしまったので乗り換えました。

画像貼り付けたりとかするときに一時的にデスクトップに置いて別アプリにドラッグしたりすると思いますが、そういう時にこのYoinkのスペースに一時的に入れといて取り出す、みたいな使い方ができます。個人的には便利だなーと思って使ってますが、デスクトップが汚れるの気にならない派の人にはそこまでなくても困らないかもしれないです。

まとめ

Macアプリ系は意外と値上がりすることが多く、買おうと思ったら前見たときより値段が倍になっている、なんていうこともザラなので欲しいと思ったときに買ってしまうのが良いかなぁと最近思っています。

アクトキャットでは自分自身やエンジニアの生産性を高めたいという人を募集中です。ご興味ある方はぜひ以下からご応募ください!

www.wantedly.com

グロースハッカーがエンジニアと会話するときに心がけている7ヶ条

はじめまして。 SideCI運営元のアクトキャットにてグロースハック及びマーケティング周りを担当している@cage0703と申します。

f:id:sideci-dev:20160706113439p:plain

今回は「グロースハッカーがエンジニアと会話するときに心がけている7ヶ条」と題しまして、スタートアップという限られたリソースの中で開発に集中しなければならない組織において、非エンジニア職である私がどういったことを心がけながらエンジニアとの業務にあたっているかという点をまとめてみたいと思います。

通常エンジニアとグロースハックは別の組織になることが多いかと思いますが、目的達成のためには2者間における入念なコミュニケーションは必須です。

ただ弊社のようなスタートアップフェーズにある組織では、エンジニアのリソースもまだまだ少ないことから、MTGなどの共有・調整作業は最小限に抑える必要があります。

よってすべての業務において時間をかけずに最適な解を導くという考えで物事を進めていくことが必要となってきます。

グロースハッカーとエンジニアの関わり

さて、いきなりですが質問です。 皆さんが関わっているプロダクトにおいて、ユーザの数や質をGrowthさせる方法はいくつありますか?

おそらく1つしかないって方は少ないのではないでしょうか?

お金やリソースなど環境を含めて制限を考慮しなければ、少し時間をとって考えてみるだけでも非常に多くの施策が出てくると思います。

そしてその施策はプロダクトサイトの改修、広告、プロダクト自体の改修と内容も多岐にわたっているはずですので、ステークホルダーは非常に多くなります。

グロースハッカーはプロダクトを深く理解し、現在の課題分析や、そこからの改善案を考えられるプロでなくてはなりません。

ただ、プロダクト(ソースコードなどの内部的な作り、仕組み)への理解においては、おそらくエンジニアを上回ることは難しいでしょう。

つまり、いくらクリティカルな課題を見つけ改善案をイメージできたとしても、最終的な実装の際にエンジニアの協力がないと、様々なパターンの中で最適な解を導くことができないのです。

以下、そんな中で私が注意していること7ヶ条を記しました。

エンジニアと会話するときに心がけている7ヶ条

1. 定性、定量の両面から考察する

  • やること例
    • 相談したい課題の要因について、定性的な推測だけでなく裏付けとなりうる定量的なデータの収集を心がける
  • 効果
    • 話す内容の裏付けが確立される
  • メリット
    • 自信を持って会話することができるようになる
    • 相手に伝わりやすいので、相談時間の短縮につながる
    • 根拠の部分がしっかりとするので、納得されやすい

2. KGIとKPIを明確にする

  • やること例
    • KGI(最終目的とする指標)とKPI(KGI達成のために見るべき指標)が何なのかをあらかじめ設定してから、分析などの作業を行う
  • 効果
    • 最終的な目的とそのために考慮するべき指標が明確になる
  • メリット
    • 話や施策がぶれにくくなる(ぶれたとしても気づきやすい)
    • 最終的な目的が指標として明確になっているので、相談された側も助言しやすい

3. 5W1Hを明確に伝える

  • やること例
    • 相談内容を5W1Hを考慮したかたちで共有する
  • 効果
    • 誰がいつ何をどうすればいいかなど、漏れなく明確に定義できる
    • 内容を容易に把握することができる
  • メリット
    • 定義が明確になることで、タスクを正確に管理、遂行することができる

4. 常にコスト(工数)をイメージする

  • やること例
    • 自分がやろうとしていること、依頼しようとしていることのコストを考える
  • 効果
    • 物事に対して費用対効果を考える癖がつく
    • 依頼するタスクの規模感(難易度)が把握できる
  • メリット
    • 無駄なタスクが発生しづらくなる
    • 依頼前に実現可能かどうかの一時判断と優先順位付けができる(事前にスケジューリングしやすい)

5. 事前にアジェンダを共有する

  • やること例
    • 相談やMTGの前にアジェンダを展開して確認を促す
  • 効果
    • 事前に議論の概要を抑えてもらうことができる
    • 資料も事前に共有しておけば、内容をより深くまで理解してもらえる可能性が高まる
  • メリット
    • すぐに本題に入ることができる
    • より本質的な質問が発生する可能性が高くなる

6. クリティカルシンキングで考える

  • やること例
    • 事象をロジカルに組み立てるだけでなく「なぜ」などの問いかけをしながら思考する
  • 効果
    • 思考をより多角的かつ深いところまで落とし込むことができる
  • メリット
    • 個人の範囲で深くまで考えることができるので、他者からの質問に対してスムーズに回答することができる(時間短縮)
    • 詳細まで考えることができるので、潜在的な課題に気づく確率が上昇する
    • 相談の場で発生するであろう質問に対する回答を、事前に網羅することができる

7. メンバーと業務以外での共通時間を持つ

  • やること例
    • お昼ご飯に一緒に行く
    • 雑談してみる
  • 効果
    • 仕事うんぬんの前に、人としての距離が縮まる
  • メリット
    • 相談事をするハードルが下がる
    • 接しやすくなるので心理状態が良化する

最後に

これらの7箇条はエンジニアとグロースハッカー間だけではなく、上司や多職種の人とのコミュニケーションの際にも役に立ちます。

多少当てはまりの悪い内容もあるかもしれませんが、観点としては様々な業務に通じるものかと思いますので、それぞれ解釈して頂けると幸いです。

現在アクトキャットでは一緒に働いて頂けるメンバーを募集しています。 Webエンジニアの方、インフラエンジニアの方、Webデザイナー、マーケターの方を積極採用中です! 社員1桁台のスタートアップに興味がある方はぜひWantedlyからご応募ください!

https://www.wantedly.com/companies/actcat/projects

「エンジニア向けサービスを支える技術」を開催しました。SideCI Study 1th

sideci_study

こんにちは。 @sumyapp です。
6月29日にSideCIチーム主催でテックイベント(勉強会)を開催しました!その様子をご紹介します:) 株式会社はてなさんのMackerelチームと共同で開催させて頂きました。

テーマは「エンジニア向けサービスを支える技術」です。
エンジニア向けサービスを提供している会社様3社に登壇して頂きました。(+弊社)

sideci.connpass.com

ダイジェスト

  • 19:30~19:40 イベント内容や登壇者様、会場のご紹介
  • 19:40~20:50 発表 + QA
    • SideCIのインフラ構築を自動化した話
    • エンジニア向けSaaSを開発・運用するということ ~ Mackerelの場合
    • Mobingi: Have FUN! with Spot Instance
    • DeployGateの作り方
  • 20:50~21:00 懇親会の準備 & 宣伝タイム & 事後アンケート
  • 21:00~22:00 懇親会わいわい(BEER & PIZZA etc…)

会場はMackerelを運営しているはてなさん。
木目の壁に銀色のロゴはカッコイイ! f:id:sideci-dev:20160704172124j:plain

19時開場後、続々と人が集まってきました。
ちなみにここはSHIBAFUというセミナールームで、床は名前の通り芝生で覆われています。

f:id:sideci-dev:20160704172158j:plain

余談ですが、普段はテントがあったり昼食を食べるスペースがあります。(設営前の風景です)

f:id:sideci-dev:20160704172212j:plain

早速始まりました!本記事では、会場説明等は省略して、いきなり発表セッション。
(※カメラマンと司会が兼任のため写真がなく...(T-T)

まずは私たちSideCIチームの若手(若手というか本記事記載時点で22歳とガチで若い)の @wata727 が発表させて頂きました。

f:id:sideci-dev:20160704172228j:plain

QAセッションでもゴールデンイメージやPush/Pull型のデプロイなどについて質問が上がりました。


続いて株式会社はてな、Mackerelチームの @songmu さんこと松木さんの発表。

f:id:sideci-dev:20160704172241j:plain

sideci-mackerel_p01.png エンジニア向けSaaSを開発・運用するということ ~ Mackerelの場合 http://songmu.github.io/slides/sideci-mackerel/#0

皆さん真剣に聞いておられます。その後QAセッション。

f:id:sideci-dev:20160704172254j:plain 深い話が盛りだくさんで、もっと聞きたかった!との声もたくさん頂きました。


続いてMobingiチームの望月さんとWaylandさんが発表。
日本語で簡単に製品の紹介->簡単な英語でのデモ+Mobingi EnterpriseでのSpot Instanceを利用したオートスケールの話。

f:id:sideci-dev:20160704172311j:plain QAではスポットインスタンスの場合のAWSでの入札額によって、インスタンスが確保出来なかった、ダウンした場合などにについての質問とお話がありました。


最後にDeployGateチームのへんてこさんがテンションアゲアゲで発表してくれました。

f:id:sideci-dev:20160704172329j:plain

大盛り上がり!

f:id:sideci-dev:20160704172402j:plain

この後、懇親会の準備を後ろで進めながら、恐縮ながら各社の宣伝タイム + アンケート等させて頂きました。

そして懇親会!
「懇親会からが本番ですよね!」と乾杯の音頭をsongmuさんから頂きスタート。

写真はここでおしまいです、ごめんなさい!
参加者30名強に対して60人分のピザ+ビールという状態で、 カメラを忘れてピザを食べるのに夢中。 もしピザの写真をお持ちの方いましたら @sumyapp まで頂けると嬉しいです!

皆様ご参加頂きありがとうございました!

LT

ダイジェストでもリンク記載させて頂きましたが、改めて皆様のスライドやブログ等へのリンクをご紹介させて頂きます。

SideCIのインフラ構築を自動化した話

スライド資料です。 https://speakerdeck.com/wata727/sidecifalseinhuragou-zhu-wozi-dong-hua-sitahua

エンジニア向けSaaSを開発・運用するということ ~ Mackerelの場合

スライド資料です。 http://songmu.github.io/slides/sideci-mackerel/#0

Mobingi: Have FUN! with Spot Instance

Mobingi Enterpriseの実際の画面でデモをしながらの話。 スライドではなく実際のサービスサイトのリンクを掲載させて頂きます。

https://mobingi.co.jp/saas-public-aws

発表にあったスポットインスタンスを使う機能はまだパブリックにはなっていないらしく、Facebook Pageの投稿から内容をご紹介させて頂きます。(2016年6月30日現在)

ワンクリックでスポットインスタンス/リザーブドインスタンス/オンデマンドの自動切り替えを行う新機能により、最大30%もの利用料金の削減に成功!Mobingiの技術を駆使したコンテナオーケストレーションにより、ゼロダウンタイムを実現しました。 https://www.facebook.com/mobingitokyo/posts/1813308045572272

DeployGateの作り方

参加ブログも書いて頂きました!(ありがとうございます!) http://henteko07.hatenablog.com/entry/2016/06/30/100000

スライド資料も上記ブログに記載があります。

Twitterでの様子

QA含め色々な方にツイート頂きました! スライドにのっていない部分や雰囲気はこちらから

togetter: http://togetter.com/li/995623

おわりに

たくさんの方にご興味持って頂き誠にありがとうございました!今後も #sideci_study というハッシュタグを使いながら、SideCIについて勉強するわけではなく、SideCIチームが聞きたいと思っている話などを中心にイベントを開いていこうと思います。

今回、100名を超える方に申し込みを頂いておりましたが、初回開催のため人数少なめで開催させて頂きました。次回以降よりブラッシュアップしていきますので、ぜひご参加下さい!

SideCIの製品やメンバーについてはこちらをご参考下さい。(メンバーも募集しております!) https://sideci.com/ja http://www.actcat.co.jp/jobs