たばりばりスタイル

たばりばりスタイル

バリバリバリ⚡︎

友人へ贈るWebエンジニア転職の学習ならこうすればいいんじゃね的な順番

最近、Webエンジニアになりたいという友人(未経験)から、転職するためのプログラミングの学習順について尋ねられた。

Web上に公開されているいくつかのロードマップから良さそうなものを共有してみたが、僕なら実際こうするかなっていうのがあったのでひとつのケースとして残したいと思います。 ※ 僕は普段 Rails を使っているので、Rails を使う前提に

僕について

  • 現在は業務委託で Web エンジニアをしている
  • SIer 2 年、Web 系 2 年弱の経験あり
    • 未経験(文系大学生)から SIer 入社、SIer から Web 系に転職を経験
  • 現在の主な利用技術は Rails / AWS / React など
  • Rails を初めて触ったのは 4.2、初めて業務で利用したの 5.1

僕のおすすめしたいロードマップについて

極力、最短で Ruby on Rails チュートリアルを始めた方がいいと思っています。

Ruby on Rails チュートリアルは本当に素晴らしい教材だと思っており、チュートリアル内で Ruby、HTML/CSS/JavaScript はもちろん、UNIX コマンドや Git に触れることができます。

チュートリアルを始める前に、Ruby、HTML/CSS/JavaScriptUNIX コマンド操作、Git を学ぶことを勧めている記事もありますが、それらは Rails チュートリアル中に適宜学ぶ形でも良いと思っています。*1

その上で、下記の流れを勧めます。*2

  1. HTML/CSS/JavaScript 基礎
  2. Ruby on Rails チュートリアル
  3. Ruby on Rails を使って自作アプリを作る

HTML/CSS/JavaScript 基礎

Progate やドットインストールでコースを 1 周。

HTML/CSS/JavaScript が何をするものか、ある程度理解できていれば良さそう。

dotinstall.com

dotinstall.com

dotinstall.com

Ruby on Rails チュートリアル

railstutorial.jp

前提知識はそろっていないので挫折率は高そう *3ですが、ひとまず 1 周することを目標に進める。 Ruby や HTML/CSS/JavaScript の書き方、UNIX コマンドの意味など、わからないことがあれば都度調べてください。

ただ、ここで意識して欲しいのはチュートリアルの内容を 100% 理解しようとしないでほしいことです。50% の理解でも上出来と考えるといいと思う。*4

1 周した後は都度調べた内容を復習して、2 周目に入ることをオススメしたい。 人によっては 1 周でいいという人もいるが、個人的には 2 周した方が気付きが多いと思う。一度通った道なので余裕を持って進められ、これまでの曖昧な知識の断片同士が繋がって、1 周目で見えなかったところも見えてくると思う。

2 周目でも意識して欲しいのは、ここでも完全に理解していなくても問題ないということ。*5

Ruby on Rails を使って自作アプリを作る

チュートリアル後は自作のアプリを作ることをお勧めします。これは、完成コードが用意されていた教材ではなく、自分で考えて作ることによって Rails と Web 開発に対して、より深い理解を得ることができるからです。

もし、可能ならチュートリアルで出てこないライブラリを使うのもありです。個人的には現場でよく使われる認証系ライブラリの Devise は使っておくと良いかなと思います。

その後余裕があったら学ぶことをおすすめしたいもの

現場に出るとチュートリアルの知識だけでは足りない知識もあります。それを補うために下記を学ぶと良いと思います。

  • テストコード (RSpec)
  • フロントエンド開発 (React.js / Vue.js etc)
  • インフラ構築 (AWS / GCP)

もし、学んだ上記を自作アプリに組み込めるとさらに良いと思います。*6

おわりに

いえ〜い、○○見てる〜? *7

*1:先に学んでも実際に必要にならないと覚えれないことが多いため

*2:僕が Rails をはじめて触った時もこんな感じでした

*3:挫折しても起き上がればいい!!!w

*4:Ruby on Rails チュートリアルは難易度はふつうに高い

*5:そもそもチュートリアルの内容を完全に理解することがゴールではない。Railsに慣れることがゴール

*6:実際に使ってみたほうが覚える

*7:分からないことがあれば都度聞いて〜!

半年フリーランスをやった雑感

2020/04 からフリーランスを始め、半年経った現状の僕の雑感についてまとめます。

はじめたきっかけ

正社員時代の給料に満足できなかったことがフリーランスになったきっかけです。

上司が他メンバーより多めに賞与をくれても、次回の査定で昇給させると言われても、満足できず、転職しても状況が変わらなかったので、自分で単価を指定できるフリーランスになりました。

正社員時代は、所属したチームに業務委託の方がいることも多く、技術レベル感を把握していたため、このレベルなら自分でもイケそうと、スキル面での不安は特にありませんでした。

順番としては、SIer -> Web 系ベンチャー -> フリーランス という現在の王道スタイルだと思います。

業務内容

エージェントを通して契約した企業に準委任契約で参画するスタイルです。

普通に Rails や React を使って開発したり、AWS を触ったり、コードレビューしたり、MTG したり、正社員と特に変わりません。

正社員自体と比べて業務はあまり変わりませんが、金額がよくなった分、責任が重く感じるようになりました。

単価について

レバテックさんの単価診断通りくらいの単価で働いています。※ エージェントを通して

プログラマ・SE(システムエンジニア)向けの単価・単金診断テスト
https://freelance.levtech.jp/service/assess/

ちょくちょく Wantedly や他求人媒体でオファーを頂くので、どこかのタイミングで直契約にもっていくのも有りかなと思っています。

フリーランスをして感じたこと

よくも悪くも作業に没頭できるなと感じます。

例えば、正社員に限定される MTG やイベントに参加せず、タスクを淡々とこなすことができます。

疎外感を感じることもありますが、"とりあえずコードを書きたい"って人にはすごくいい環境だと思います。

また、ベースとなる稼働時間があるため、基本的に残業はなく、私生活も安定しやすいと思います。もしリリース前など稼働が多くなっても、オーバーした分の額をいただけたので満足です。(単価が高いので正社員時代と比べ物にならない残業代です。)

今のところフリーランスになってからメリットしかないので、1年経過した時点で同じようなまとめを書こうと思います。 その頃は確定申告も経験するので考えが変わるかも?です。

以上です。

RSpecのCustom Matcherをカジュアルに追加している

Rails で開発、テスト (RSpec) していると、Custom Matcher を作りたくなるケースがあります。

例えば下記のようなケースです。

RSpec.describe User, type: :model do
  context 'Userのemailがnilの場合' do
    subject { build :user, email: nil }
    before { subject.valid? }

    # Userのemailがnilの場合にemailのエラーを持つか確認
    it { expect(user.errors.has_key?(:name)).to eq true } # ワンライナー
  end
end
# テストを実行
$ bundle exec rspec -fd
User
  Userのemailがnilの場合
    is expected to eq true

このテストだと出力でテスト内容が理解できませんし、テストの内容と出力にズレが生じています。(User の email が nil の場合に true が期待されているように見える

個人的にこの出力のされ方が好きではないため、expect の引数であれこれ記述しないようにしています。

このようなケースでは下記のように Custom Matcher を自作してテストをしています。

# Custom Matcher
RSpec::Matchers.define :have_error do |expected|
  match do |actual|
    actual.errors.has_key? expected
  end
  description do
    "have an error in #{expected}"
  end
end

RSpec.describe User, type: :model do
  context 'Userのemailがnilの場合' do
    subject { build :user, email: nil }
    before { subject.valid? }

    it { is_expected.to have_error :email }
  end
end
# テストを実行
$ bundle exec rspec -fd
User
  Userのemailがnilの場合
    is expected to have an error in email

上記の出力のように Custom Matcher を使うだけで、テスト内容が出力からある程度理解でき、テストの内容と出力で起こるズレを減らせます。

なので、既存の Matcher で it { is_expected.to matcher_name expected } のように書けないテストには、カジュアルに Custom Matcher の追加を検討していくようにしています。

ただ、これまでの現場ではあまり Custom Matcher を使っているところがなかったので、実際どうなんだろう。

以上です。

コロナ禍で4ヶ月フルリモートワークを経験した感想

コロナにより、業務委託として独立したタイミングからずっとフルリモートワークで働いて 4 ヶ月経ちました。

今回はそのフルリモートワーク経験の感想、個人的なメリット・デメリットや気をつけていることをまとめたいと思います。

ここでのフルリモートワークとは?

  • 参画日だけ出社、その後リモートで働いている
  • 4 ヶ月働いて出社は 1 回だけ (一時的に出社したのを含めると 2 回

※ 現在参画している企業ではエンジニアのリモートワークが推奨されているため、コロナの状況が収まってもフルリモートが続く予定

実際に 4 ヶ月フルリモートワークしてみてどうだったか

メリット

  • 食費を抑えれる (出社すると同僚とのランチ代がかかる
  • 通勤時間が減る分、プライベートの時間が増える
  • ベッドを使える (寝転がりながら作業ができる、休憩中にベッドで昼寝できる
  • トイレが混まない
  • 作業に集中できる (社内だと起こるイベントに巻き込まれないため
  • 文字ベースのコミュニケーションスキルがあがる? (少ないやりとりになるように文字を送るようになる?
  • 自制心が鍛えられる

デメリット

  • Slack や Zoom だけだと取りにくいコミュニケーションが発生する
  • 同僚の顔がわからないままになる (チームメンバー 1 人も顔がわからない
  • 人の目がないので気が抜ける
  • 公共料金があがる

フルリモートで働く上で気をつけていること

現在自分がなにをしているか分かるようにしておくことを意識しています。 例えば Issue や PR などで対応状況を目に見える形で伝えられれば良いのですが、進捗が悪く対応状況が目に見えにくい場合は分報 (times) チャンネルに対応状況をこまめに書くようにしています。

まとめ

個人的にはリモートワークは自分に合った働き方だなという印象です。 特に現チームが個人の裁量に任せて、放任主義なスタイル (タスクのアサインもある程度個人の自由) なので良い感じです。

今後はフルリモートが一般的になればいいなと思っています。

「情熱プログラマー」を読んだ

プログラマとしての情熱を補充するために「情熱プログラマー ソフトウェア開発者の幸せな生き方」を読みました。

  この本はソフトウェア開発者のキャリアや人生の考え方の戦略が書かれた本で、「SOFT SKILLS ソフトウェア開発者の人生マニュアル」に近く、読んでいて熱くなるものがある本でした。

今後も読み返したいと思った章

第 1 章 市場を選ぶ

4. 一番の下手くそでいよう

組織やチームの中で自分が一番下手くそな環境がチャンスと思える章。 (一番下手くそな環境 == 自分より優れている人たちと働けている

現在、業務委託で参画してる会社でテックリードとシニアレベル業務委託と 3 人でチームを組んでおり、自分が 1 番下手くそだなと毎日感じている僕にはぴったりの章だった。この環境で成長してやるぜ!って思える。  

6. 親の言うことを聞くな

周りとかリスクを考えず、本当に自分がやりたいことをやるべきだと考えさせられる章。

最後に出てくる補足の「GitHubに専念するためにMicrosoftからの30万ドルを断った」という話が読んでいてワクワクする。

第 4 章 マーケティング... スーツ族だけのものじゃない

39. 業界で名前を売ろう

良質なエンジニアとしてのキャリアを積むために、ブログをちゃんと書こうと思う章。

「SOFT SKILLS ソフトウェア開発者の人生マニュアル」でも同じような章があった。エンジニアとして働いてく上でブログは必須だなと思える。。

第 5 章 研鑽を怠らない

44. 既に時代遅れである

新しい技術を学ばないことに危機感を持てる章。

これまで目先の仕事ばかりに囚われて、将来の自分のための勉強 (投資) をしていなかったので、考えを改めたいと思った。最近はプライベートで Golang を触り始めたので、このような時間を大切に、確保していきたい。

まとめ

読んでよかった。

以上です。

Railsでchubby model対策になるべくConcernを利用するなら

今回は、Rails Way な Fat モデルのダイエット方法である Concern をなるべく使うようにする場合、個人的にどうすればいいかをまとめてみます。

Concern とは

Concern を使えば、他クラス (モデル) と共有できる機能 (関心) を外に切り出すことができます。

使い方は下記から見れます。 signalvnoise.com

github.com

DHH の Tweet では、どのような Concern を作るかイメージが湧きます。(見た目クール

Concern を意識してモデルを考える

モデルを設計するときに、xxx という機能に関連する実装を xxxable の Concern に切り出すことで関心事を外に切り出すことができ、使いまわすことが出来ます。

例えば、あるモデルには 完了という状態を保持する機能 (完了機能) が存在する場合、その機能を Concern に切り出せないかと考えます。

まずはこの機能に関連して必要となる実装を抜き出します。

  • 完了状態のレコードをひく completed という scope
  • 完了状態を確認する completed? メソッド
  • 完了状態に変更する complete! メソッド

この実装を Concern 化するなら下記のようになります。

# app/models/concern/completeable.rb
module Completeable
  extend ActiveSupport::Concern

  included do
    # 完了状態のレコードをひく scope 
    scope :completed, -> { where.not(completed_at: nil) }
  end

  # 完了状態を確認するメソッド
  def completed?
    completed_at?
  end

  # 完了状態に変更するメソッド
  def complete!
    update!(completed_at: Time.current)
  end
end

完了機能をもつモデルらに include します。

# 完了機能をもつ Task モデル
class Task < ApplicationRecord
  include Completeable
end

# 完了機能をもつ Project モデル
class Project < ApplicationRecord
  include Completeable
end

テストはどう書くか

対象モデル用に shared_examples を作る方法と Concern 用の Spec を作る方法がありそうです。

対象モデル用に shared_examples を作る方法

クラスメソッドの確認には described_class を使い、レコード生成には FactoryBot に登録されている factory 名を渡してあげればうまく共通化できました。

# spec/models/project_spec.rb
RSpec.describe Project, type: :model do
  include_examples 'Completeable', :project
end

# spec/models/task_spec.rb
RSpec.describe Task, type: :model do
  include_examples 'Completeable', :task
end

# spec/support/examples/model/concerns/completeable.rb
RSpec.shared_examples 'Completeable' do |factory_name|
  describe '.completed' do
    subject { described_class.completed }
    let(:target_record1) { create factory_name, completed_at: 10.days.ago }
    let(:target_record2) { create factory_name, completed_at: 10.days.since }
    let!(:target_records) { [target_record1, target_record2] }
    let!(:other_record) { create factory_name, completed_at: nil }

    it 'returns the target records' do 
      is_expected.to match_array target_records
      is_expected.to_not include other_record
    end
  end

  describe '#completed?' do
    subject { record.completed? }

    context '完了状態の場合' do
      let(:record) { create factory_name, completed_at: Time.current }
      it { is_expected.to be true }
    end

    context '完了状態ではない場合' do
      let(:record) { create factory_name, completed_at: nil }
      it { is_expected.to be false }
    end
  end

  describe '#complete!' do
    subject { record.complete! }

    context '完了状態の場合' do
      let(:record) { create factory_name, completed_at: Time.current }
      it { expect { subject }.to_not change(record, :completed?) }
    end

    context '完了状態ではない場合' do
      let(:record) { create factory_name, completed_at: nil }
      it { expect { subject }.to change(record, :completed?).from(false).to(true) }
    end
  end
end

Concern 用の Spec を作る

下記リンクを参考にさせていただきました。

qiita.com

完了機能をテストにするには下記のようになりました。

# spec/models/concerns/completeable_spec.rb
RSpec.describe Completeable, type: :concern do
  before(:all) do
    m = ActiveRecord::Migration.new
    m.verbose = false
    m.create_table :completeable_models do |t|
      t.datetime :completed_at
    end
  end

  after(:all) do
    m = ActiveRecord::Migration.new
    m.verbose = false
    m.drop_table :completeable_models
  end

  class CompleteableModel < ApplicationRecord
    include Completeable
  end

  describe '.completed' do
    subject { CompleteableModel.completed }
    let(:target_record1) { CompleteableModel.create completed_at: 10.days.ago }
    let(:target_record2) { CompleteableModel.create completed_at: 10.days.since }
    let!(:target_records) { [target_record1, target_record2] }
    let!(:other_record) { CompleteableModel.create completed_at: nil }

    it 'returns the target records' do 
      is_expected.to match_array target_records
      is_expected.to_not include other_record
    end
  end

  describe '#completed?' do
    subject { record.completed? }

    context '完了状態の場合' do
      let(:record) { CompleteableModel.create(completed_at: Time.current) }
      it { is_expected.to be true }
    end

    context '完了状態ではない場合' do
      let(:record) { CompleteableModel.create(completed_at: nil) }
      it { is_expected.to be false }
    end
  end

  describe '#complete!' do
    subject { record.complete! }

    context '完了状態の場合' do
      let(:record) { CompleteableModel.create(completed_at: Time.current) }

      it do
        expect { subject }.to_not change(record, :completed?)
      end
    end

    context '完了状態ではない場合' do
      let(:record) { CompleteableModel.create(completed_at: nil) }

      it do
        expect { subject }.to change(record, :completed?).from(false).to(true)
      end
    end
  end
end

Concern を使った感想

メリットは xxx 機能はこのテーブル設計で〜、このメソッドで〜という流れで Concern をベースにモデルの実装方法が決まるので、統一感が出るのではないかと思っています。

デメリットとしては実際の開発だと、その機能の関心 (Concern) の分離先 module をどこにすればいいか、どういう命名で作るかなど迷いポイントがありそうだなという点です。

ただ、個人的に Concern によるダイエットは、Rails 謹製のダイエット方法でもあるので、変に Rails Way を外れて独自のレイヤー追加でダイエットさせるよりは良い選択だと思っていて、正しく追加された Concern は機能毎に切り出されたファイルになると思うので、可読性もいいのではと考えています。

以上です。

正社員から個人事業主になるときにやったことをまとめる

4月から常駐型の業務委託で、ペーペー個人事業主 (フリーランスエンジニア) として働いています。

今回は、正社員から個人事業主になる際にはやった手続きや届出、事前準備などを残します。

必須なこと、たぶん大体の人がやること

国民健康保険の加入手続き / 国民年金の加入手続き

  • 手続き場所
    • 市区町村役場で手続きを行う
  • 事前準備
    • 前職に退職証明ができる書類を発行してもらう
    • 書類の記入は役場で行う
  • 期限
    • 退職後 14 日以内に手続きを行う
  • 持っていったもの
    • 印鑑
    • 身分証明書
    • マイナンバー通知カード
    • 退職証明ができる書類
    • 年金手帳
  • その他
    • 国民健康保険/国民年金の加入手続きは同時に対応してもらえた
    • 場所によると思いますが、1 時間弱ほどかかりました

開業届出書提出 / 青色申告承認申請書提出

そのほかの事前準備など

  • 正社員のうちに引越し (賃貸契約)
  • 正社員のうちに家電購入 (ローン契約)
  • 個人事業主用のクレジットカード作成
  • 個人事業主用の銀行口座を作成
  • 各種引落しを個人事業主クレカor口座に変更

おわり

4月は業務委託初参画と、各種手続きと届出でバタバタしていましたが、やっと落ち着きそうです。