patorashのブログ

方向性はまだない

オープンセミナー岡山2019に参加してきた

6月29日(土)に開催されたオープンセミナー岡山2019に参加してきました。

oso.connpass.com

今年のテーマは「Technology X Society」で、講演タイトルからは技術で社会を良くしていく話、ということかなと考えてました。

当日のツイートはtogetterにまとめられています。毎度毎度ありがとうございます。

togetter.com

講演内容の特徴

今回は講師の方々は経営層寄りの方が多く、本当に興味深いというか心に刺さる話が聞けました。

テクノロジーで社会を変える系

テクノロジーで社会を変えていくという点では、Kyashの中澤 望さんの講演で、Kyashのビジョンや戦略を知ることができました。その中で、「情報、コミュニケーションは進化したが、お金はまだまだ。お金を進化させたい」という話がありました。こういうところでFinTechが熱くなってるんだなというのが伝わってきました。確かにお金のやり取りにはリードタイムといいますか、売上が上がってから実際に支払われるまでにかなりのタイムラグがありますし、手数料も結構取られます。これをKyash払いにすることで、利用者側の都合で売上をすぐKyashとして利用できるのは、コスト的にも体験的にも大きな変化だと思います。クレオフーガがAudioStockの売上をKyash払いで受け取れるようにしたという話がありましたが、これはクリエイターにとっては売上をすぐに受け取れるし、すごく良い試みだと思いました。個別だと大きな売上が立ちにくいマーケットだと、売上を受け取る前に力尽きてしまいそうなので、すぐに売上を受け取られるという成功体験を得やすいというのは、クリエイターのモチベーションアップにもなりそうだなと思いました。

ビズ・クリエイションの初谷 昌彦さんの講演も、住宅業界を変えていきたいという熱意と、戦略が面白かったです。モデルハウスではなく、住宅見学会のスケジュールや場所を見える化して、リアルな家を見学してもらうというのは、家を既に建てている私からすると、「当時あってほしかったなぁ~!」と思いました。モデルハウスの見学や、住宅見学会に行くのって、めちゃくちゃ楽しいんですが、基本的に有名どころのビルダーしか情報が入ってこないので、工務店の情報とかほぼありませんでした。うちも色んな住宅展示場を回ったりしましたが、基本的には大手しかありませんでした。調べるのも労力がかかるので、住宅雑誌を買ったり、サイトから資料取寄せしたり等はしました。資料を読むのも面白いのですが、検索性はありませんし、同じようなことが書いてあるようにも感じ始めるので、実際に見て、説明が丁寧か、とかがやはり大事だなと思います。 うちが建てたところは結構IT化されていたので、やりとりはメール or LINEで、建設中はWebカメラで様子を見たり、途中経過の画像が随時追加されていったりしてよかったのですが、初谷さんの話だとやはり工務店はまだまだIT化されていないということでした。が、それがまた余地があって面白いのだろうなと思います。建設Techも楽しそう! 大手が儲かって下請けが搾取される構造になっているのが課題で、そこに取り組んでいるというのがIT業界にも似たところがあるので共感した人は多かったんじゃないかなと思います。

経営者目線や組織の話系

アイネットの山本 由佳里さんの講演は、起業ではなく父親からの事業継承で社長になったというならではの話だったなと感じました。エンジニア上がりだからこそ感じる違和感や責務を持って、社長業をされているからこその重い言葉や熱い筋の通った信念があり、こういった方が社長でアイネットの社員は幸せだろうなと思いました。 エンジニアの幸せの秘訣についての中で、励ましの言葉になったのは、「アイデアなんてなくてもいいと思おう」でした。アイデア勝負な昨今でろくなアイデアが浮かばない自分はダメなんじゃないだろうか?と割とすぐに考えてしまいがちだけれど、アイデアは地続きでしか出てこないから、出てくるまで気長に待ちながら技術を磨くなりしていればいいかなと思えました。 IT業界に限らない話かもしれないけれど、結構、「呪いの言葉」みたいなものがあって、その呪縛に知らず知らずに囚われてしまって、幸せを感じづらくなっているんじゃないか?と講演を聞いて思いました。経験がないから、年だから、マイナーな言語だから、男だから、女だから…のような言葉。 あと小さい案件から大きな経験を得たというの、めちゃくちゃ同意で、これは個人開発でも言えることなんだけれど、小さい案件で一通りの経験ができるというのは本当に尊いことだと後でわかりました。

ヌーラボの橋本 正徳さんの講演も面白かったです。twitterで質問を集めて途中途中で回答しながら進めていくのはリアルタイム感があってよかったです。ヌーラボの製品はbacklogとcacooは知っていましたが、typetalkは知りませんでした。cacooは時々使っていますが、他は全然使ったことがなく…。 一番大事なことに掲げていたのが「哲学」でした。ビジョンより大事って言われてたけれど、確かにそうだなと思いました。「ツールを導入するということは、そのツールを作っている会社の哲学を導入するのと一緒」というのは、重い言葉だなと思います。安易に値段を基準にしてツールを導入してしまうと、その哲学に引っ張られてしまうこともあるだろうな、と思います。個人で色々ツールを探していて、そのときに感じていたものを言葉にしてもらえたなと思いました。 組織設計が主な話題だったと思いますが、自分的にはアンガーマネジメント研修いいなぁ…と思いました。 個人的には怒ってるまでいってないんだけれど声がでかくなるみたいで怒ってると思われてしまうことがあり、気を付けているんだけれどずっとそのイメージが残っているのか最近でも延々とそのことを指摘されることがあってもう正直ウンザリしているんですが、延々と言われるくらいなら研修受けてみたいなぁと強く思いました。指摘されるだけだと、個人で気を付けてるつもりでも、別にそれからフィードバックをくれるわけでもないし…。 そういえばリーナスもそういう研修受けたという話だし、アンガーマネジメント、効果絶大なのでは…。

翔泳社の岩切 晃子さんの講演は、手書きスライドでOHPを思い出しました。講演内容は「全ては未来会議から始まった」というタイトルで、組織パターンという書籍のワークショップに参加して、それを仕事にも使ったという話だったのですが、講演中に気持ちが昂ってしまうほど、壮絶であり、しかしとても大勢の良い仲間に協力していただいて成し得たのだなと思います。生の講演ならではのことでオフレコだけれど貴重な体験を沢山話していただけて、とても感銘を受けました。心理的安全の確保や、小さくてもいいから成功体験を早く作ることなど、ノウハウもありつつの素晴らしいお話でした。

スーパーマン

高野さんの講演「ひとりでできるもん!」は、かけなびさんが「あなたしかできないでしょ!」と言ってたけれど、超すごかったです。バスの運行システムを1人で作成して全国から声がかかるようになってて、またそのシステムがめちゃくちゃ良くできていてコストも安い…。ゲーム作りから様々なノウハウを得て、絵も音楽も動画もシステム開発も全部1人でやってしまうというのはほんまにスーパーマンだなと思います。え、音楽も!?って思いましたもん。それがまさかの、バンドをやっていたから音楽も作れたというエピソード、そして、実は調理師免許も持っているとか…。 1人でできるメリット、デメリットのところで、「人を使うのが苦手だから。そして絶対にブラック企業になる」というふうに語っておられたので、これが正解なのだろうなと思いました。特異だけれど、こういうケースもあるのだろうと。 なんていうか、技術トレンドの選択が~とかよりも、やってみてからでいいじゃん、という気持ちになりました。もっと頑張らんと!という勇気をいただけました。

全体を通して

普段なかなか聞けない話を聞く機会を得られて本当によかったです。OSO最高!阿部さんすごいなー!と思いました。 また、旅するagile本箱という展示があり、休憩時間にパラパラと読んだのですが、気になる本があったので、また注文して読んでみようと思います。

実行委員の皆様、お疲れさまでした。ありがとうございました。

再帰クエリを書いてみた

まんまなのですが、再帰クエリを書いてみたら一発で処理がキマったのでよかったという話です。

Railsで親子関係を表現するデータで再帰処理をやっていたのですが、当然ですが再帰するたびにクエリが発行されていてなんだか微妙でした。 そうこうするあたりで、「再帰クエリ」という文字を見かけたので、「お、これはやってみるチャンスやな」と思ってやってみた次第。

モデルの定義

テーブル作成

Userモデルの親子関係を表現するテーブルとして、familiesテーブルを作ったとします。 外部キー制約とユニーク制約を入れておきました(子供が2つの親を持てないようにするため)

class CreateFamilies < ActiveRecord::Migration[5.2]
  def change
    create_table :families do |t|
      t.integer :parent_id, null: false
      t.integer :child_id, null: false

      t.timestamps
    end
    add_foreign_key :families, :users, column: :parent_id
    add_foreign_key :families, :users, column: :child_id
    add_index :families, :child_id, unique: true
  end
end

Familyモデルの定義

検証を定義しておきます。子供が自分の親を子供として登録できないような検証check_circular_referenceを定義しておきました。ここで使っているmy_familiesメソッドで、再帰クエリを使っています。

class Family < ApplicationRecord
  belongs_to :parent, class_name: 'User'
  belongs_to :child, class_name: 'User'

  validates :parent,
            presence: true,
            uniqueness: { scope: :child_id, message: '既に子供として登録済みです' }
  validates :child,
            presence: true,
            uniqueness: { message: '既にどこかの子供として登録済みです' }
  validate :check_circular_reference

  private

    def check_circular_reference
      if parent.my_families.exists?(id: child)
        errors.add(:child, '親や子供の子供を登録することはできません')
      end
    end
end

Userモデルの修正

透過的に親子関係が扱えるように関連を記述し、あとは親子関係とかをチェックするためのメソッドを追加等。再帰クエリはmy_familiesメソッドで使っています。

class User < ApplicationRecord

  # 親子関係を参照するための関連を記述
  has_many :families,
           foreign_key: :parent_id,
           dependent: :destroy

  has_many :children,
           class_name: 'User',
           through: :families,
           foreign_key: :child_id

  has_one  :family,
           foreign_key: :child_id,
           dependent: :destroy

  has_one :parent,
          class_name: 'User',
          through: :family,
          foreign_key: :parent_id


  # 親かどうか確認する
  # @return [Boolean] 子を持っているかルート親であればtrueを、それ以外はfalseを返す
  def parent?
    self.children.exists? || self.root_parent?
  end

  # 子かどうか確認する
  # @return [Boolean] 子ならばtrueを、親ならばfalseを返す
  def child?
    self.parent.present?
  end

  # ルート親かどうか確認する
  # @return [Boolean] ルート親ならばtrueを、そうでなければfalseを返す
  def root_parent?
    !self.child?
  end

  # ルート親を取得する
  # @return [User] ルート親を返す
  def root_parent
    return self if root_parent?
    self.parent.root_parent
  end

  # 親子を全て返す
  # 再帰問い合わせを使って子を取得する
  # @return [User::ActiveRecord_Relation] メソッドを実行したUserの家族を全て返す
  def my_families
    User.from(<<~SQL)
      (
        WITH RECURSIVE my_families AS (
          SELECT
            families.parent_id
            , families.child_id
          FROM families
          WHERE #{User.sanitize_sql_for_conditions(['parent_id = ?', self.root_parent.id])}
          UNION ALL
          SELECT
            families.parent_id
            , families.child_id
          FROM families, my_families
          WHERE families.parent_id = my_families.child_id
        )
        SELECT *
        FROM #{User.quoted_table_name}
        WHERE id IN (
          SELECT parent_id AS user_id
          FROM my_families
          UNION
          SELECT child_id AS user_id
          FROM my_families
        )
      ) users
    SQL
  end
end

再帰クエリ

再帰クエリに関しては、Let's Postgresにちょうどいい説明があって助かりました🙏

lets.postgresql.jp

木構造のデータを取っていくのにちょうどいいです。ただし、複雑な木構造だったりするとパフォーマンスが悪かったり、循環してしまっているような構造だと無限ループになる可能性があるため、取り扱いには注意が必要です。今回は循環しないように検証を追加しているため、単純な木構造のデータですし、そこまで親子関係も深くならない想定での実装です。

WITH句

PostgreSQLにはWITH句があります。これは、サブクエリに名前を付けることができる機能です。複雑なSQLの場合、JOINしたりUNIONしたりする際に同じサブクエリを書くケースがありますが、そういうのはWITH句を使って事前に一時テーブルを作っておけば、シンプルに書くことができます。

Before

なんかいい例が思いつかなかったのですが、例えばcurrent_loginsという今期のログイン実績のテーブルと、previous_loginsという前期のログイン実績のテーブルがあったとして、それの権限がadminのもののみを合わせて抽出したいとします。すると、以下のような感じで、INNER JOINの条件が同じになります。

SELECT current_logins.*
FROM current_logins
INNER JOIN (
  SELECT id, name
  FROM users
  WHERE role_id = 1
) admin_users ON current_logins.user_id = admin_users.id
UNION ALL
SELECT previous_logins.*
FROM previous_logins
INNER JOIN (
  SELECT id, name
  FROM users
  WHERE role_id = 1
) admin_users ON previous_logins.user_id = admin_users.id
After

これをWITH句を使うと、以下のように書くことができます。同じ条件のサブクエリの再利用が捗りますね。

WITH admin_users AS (
  SELECT id, name
  FROM users
  WHERE role_id = 1
)
SELECT current_logins.*
FROM current_logins
INNER JOIN admin_users ON current_logins.user_id = admin_users.id
UNION ALL
SELECT previous_logins.*
FROM previous_logins
INNER JOIN admin_users ON previous_logins.user_id = admin_users.id

WITH RECURSIVE句

WITH RECURSIVE句は初回の取得データを元に再帰的にUNION( ALL)を繰り返す等をしてデータを取得できます。あとはWITH句と同じく、その後に続くクエリで利用することが可能です。 わかりやすくするために、さっきのUserモデルで書いていたものを修正したものが以下になります。初回のparent_idを1に指定しています。

WITH RECURSIVE my_families AS (
  SELECT
    families.parent_id
    , families.child_id
  FROM families
  WHERE parent_id = 1
  UNION ALL
  SELECT
    families.parent_id
    , families.child_id
  FROM families, my_families
  WHERE families.parent_id = my_families.child_id
)
SELECT *
FROM users
WHERE id IN (
  SELECT parent_id AS user_id
  FROM my_families
  UNION
  SELECT child_id AS user_id
  FROM my_families
)

UNION ALL以下では、FROMにWITH RECURSIVEで指定したmy_familiesテーブルを追加し、WHERE条件で利用しています。ここでは、User id 1の子供が親になっているデータを抽出、その子がまた親になっているデータを抽出…というように繰り返し処理が行われます。

そして、再帰クエリで取得できたmy_familiesを利用して家族として該当するidのみをusersテーブルから抽出しています。一発で階層構造のデータを取得できるのはいいですね!👍

やってみた感想

最初は同じことをする処理をRubyで実装していたのですが、だんだん頭がこんがらがってきてしまっていました。シンプルな再帰処理ならサクッと書けるのですが、複雑なやつは苦手です😭何度もクエリが発行されてパフォーマンスも悪くなりがちですし。しかしSQLならば1度の発行で済むため、パフォーマンスもよさそうです。 とはいえ、プログラムが複雑になるか、SQLが複雑になるか、というトレードオフにはなるんですが、これくらいだったら再帰クエリを使ってもいいかなと思えました。

また、こういう親子関係を管理するgemにancestryというやつがあるのですが、再帰クエリをマスターしたら、これを使わずに済むのではないか?と思えました。ancestryは1つのカラムに/で子idを区切って登録したりしているので、なんとなく辞めたいなという気持ちがあります。再帰クエリを使ったancestry的なgemを作ってみたいと考えています(いつになるやら)

RailsにPR送ったらマージされた

Railsに含まれているgem web-consoleに自分のPRが取り込まれた🎉

github.com

感動を残しておくためにブログに書いとく。

事の始まり

先日、Rails 6.0.0 rc1でrails newして、ごにょごにょと進めていたら、ログに以下のメッセージが出ていた。

Cannot render console from Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255

今はWindowsからHyper-V上のUbuntuに接続して開発しているため、web-consoleがホスト側のIPを許可していないってことだった。早速ググって、設定を追加しようとした。

qiita.com

おー、これだこれだ…と思い、追加。

config.web_console.whitelisted_ips = '0.0.0.0/0'

そして、再度アクセスすると、まだログが出るじゃないですか。どういうことですか、これは…。

ソースコードを読みに行く

すると、最新のweb-consoleのコードでは、config.web_console.whitelisted_ipsではなく、config.web_console.permissionsを利用するようになっていた。

Railsアプリ側でwhitelisted_ipspermissionsに変更すれば、エラーログも消えて問題なくなった。

config.web_console.permissions = '0.0.0.0/0'

しかし、互換性を保つため、config.web_console.whitelisted_ipsも利用できるように見えていたんですよ、一見は。

initializer "web_console.permissions" do
  if permissions = config.web_console.permissions || config.web_console.whitelisted_ips
    Request.permissions = Permissions.new(permissions)
  end
end

しかし、上のほうでconfig.web_console.permissions = %w( 127.0.0.1 ::1 )って初期化されているため、config.web_console.permissionsnilになることは絶対になく、config.web_console.whitelisted_ipsが使われることはないことになっていた。これ今までのコードで設定していた人たちがRails6にアップデートしたら急にweb-consoleが使えなくなる地雷じゃない?というかバグじゃない?と思い、PRを作ってみることに。

Pull Request作成

ひとまず、上記のところの順番を逆にするだけのPRを作って送った。最初にconfig.web_console.whitelisted_ipsを評価してしまえばそれでいいからだ。

initializer "web_console.permissions" do
  if permissions = config.web_console.whitelisted_ips || config.web_console.permissions
    Request.permissions = Permissions.new(permissions)
  end
end

そしたら、「テストを追加してくれ」と言われたので、やろうとしたのだけれど、うまくいかなかった。railtieのテストでRailsの初期化をもう一度やる仕組みが定義されていたのだが、それに則るとconfig.web_console.permissionsが設定されていなくてnilになっており、もしwhitelisted_ipsに値を入れても評価されるかどうかのテストがあったとしてもパスしていただろう。つまりテストもバグってた。

どーしたもんかなー…と思い悩んでいたのだけれど、コードとテスト見ると、ループバックアドレス127.0.0.1のこと)はデフォルトで常に許可されるように定義されていたため、「あれ?これってconfig.web_console.permissions = %w( 127.0.0.1 ::1 )の初期値の定義いらないよな?🤔」と思い、初期値の行の削除とpermissionsの定義を行うメソッドを必ず実行するように修正した。

# config.web_console.permissions = %w( 127.0.0.1 ::1 ) は削除済み
initializer "web_console.permissions" do
  permissions = config.web_console.permissions || config.web_console.whitelisted_ips
  Request.permissions = Permissions.new(permissions) # ifが不要だったので外した
end

whitelisted_ipsを使ってもpermissionsが設定されることを確認するテストを追加して、コードを引用しながら拙い英語で頑張ってみたところ、マージされた!!😂Rails6には間に合う模様。嬉しい!!

感想

やってみるもんです。

トレイボーを貰った

誕生日だったので、妻に最近気になっていたトレイボーをプレゼントに買ってもらいました😊 トレイボーはヨギボーのトレイ付きクッションです。膝にPCを置いて作業をするとPCが熱くなったり、肩が凝ったりしていたので、楽な姿勢で安定して作業したかったのです。 届いたので早速レビューを!

箱はしっかりとしています!

f:id:patorash:20190516072127j:plain

プチプチで丁寧な梱包が行われていました。

f:id:patorash:20190516072159j:plain

緑のクッションと引っ掛かりのための両面テープ付きバーがありました。

f:id:patorash:20190516072254j:plain

恐らくバーを貼るとこんな感じになるかと思います(が、貼っていません) 溝がありますが、そこにはタブレットをひっかけることができます。動画を見るためにタブレットを持たなくていいのでいいですね!一度Kindle Fireで動画を見てみたのですが、とてもよかったです。

f:id:patorash:20190516072355j:plain

実際に使うとこんな感じです。ビーズクッションなので、平行にするだけでなく、傾けたりしても太ももにフィットして安定性がありますし、PCの熱さもないし、めちゃくちゃ快適です!普通のソファーがPCの作業机として使えます。猫背にならずにキーボードを打てるので肩凝りにもならなさそうです。

f:id:patorash:20190526182130j:plain

感想

椅子さえあればどこでも作業しやすくなりそうです。例えば、長時間移動の時とかに持っておくとよさそう!自宅で作業するのもいいですが、車で作業するとかにも使えそう。非常にいいものをプレゼントしてもらったなと思います👍

RubyでUTF-8のCSVをExcelに変換するコマンドを作った

お客様や社内の他の部署のメンバーとファイルのやりとりをすることってあると思うのですが、いつも大変なのが、CSVファイル。HerokuのDataclipsがバージョンアップされてExcel形式でダウンロードできなくなったので、仕方なくCSVでダウンロードして、Excel起動してインポートでそのCSVを取り込んで…ってやっていたのですが、ファイル数が多くなると、とても苦痛です。

それができるようなコマンドやサービスなりを探そうとしたのですが、いいのがなかったので、もう面倒だから自分でgemを作りました。

rubygems.org

実行コマンド付きのgemなので、CLIで利用可能です。

CLIで利用

$ csv2excel -f foo.csv # => foo.xlsxが作成される
$ csv2excel -f bar/baz.csv # => bar/baz.xlsxが作成される
$ csv2excel -d ./bar # => barディレクトリ内の全てのcsvファイルからxlsxファイルを作成する

Rubyのコードで利用

CSVクラスをオープンクラスしてメソッドを追加したので、利用も簡単。

require 'csv2excel'
CSV.to_xlsx(file: 'foo.csv') # => foo.xlsxが作成される
CSV.to_xlsx(dir: './bar') # => barディレクトリ内の全てのcsvファイルからxlsxファイルを作成する

まとめ

ほとんどgem axlsxのおかげです。でも我ながらめっちゃ便利で重宝しています。

WindowsでChromeが遅かったのはWindows Update(1803)が原因だった

Windows10のChromeで、はてなブログがとてつもなく重くなって大体見られない件で私は数か月ほど疲弊していました。そのため、WindowsではEdgeを使っていました。別にEdgeも悪くはないのですが、Chromeのほうが拡張機能を色々入れていて使いやすいのでやっぱりそちらを使いたいなと思って原因を調べ始めたら、どうもWindows Updateが原因で起きる模様。

www.anchumosaku.net

詳細は上記のブログに譲るとして、 Cryptographic Servicesを停止すれば改善するそうです。試しにコルタナでserviceと打って、サービスウィンドウからCryptographic Servicesを停止してみました。

f:id:patorash:20190517224948p:plain
Cryptgraphic Servicesの停止を行う

停止した状態で、はてなブログChromeで開いてみたところ、あっという間に開きました。今までの「応答がありません」はなんだったのか…。

ちなみにCryptgraphic Servicesの再起動でも症状は改善するそうで、再度起動させても確かにChromeでブログが見られました。これでいいかなとも思ったのですが、やけにファンが回り始めるので、やっぱり無駄に負荷が上がっているみたいだし、症状がまた起きるのもストレスなので、上記のブログに書かれていたレジストリの編集を行いました。レジストリの編集は自己責任で!バックアップはちゃんと取ってからやりましょう。

上記の記事に従って、Chromeの停止、Cryptgraphic Servicesの停止を行ってから、レジストリエディタを起動して作業していました。ここで、躓きます。上記の記事では、以下のように書いてありました。

レジストリの左ウィンドウのエクスプローラに一覧が表示されますので、「コンピューター\HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates\Root」へ移動します。 ここで、Rootの下にあるProtectedRootsだけは権限により編集できないため、アクセス許可の設定を変更する必要があります。 上の画像のように(上記のサイトでは画像がある)、ProtectedRoots上で右クリックすると「アクセス許可」の項目があるので、アクセス許可ウィンドウを開き、今ログインしているユーザに「フル コントロール」を与えます。

しかし、アクセス許可を与えようとすると、アクセス拒否されるのです😰 「ProtectedRoots」をキーワードにして検索したら、以下の記事が見つかりました。

twig-jp.blogspot.com

所有者を変えなければいけない模様。

f:id:patorash:20190517231214p:plain
RrotectedRootsのアクセス許可から、詳細設定をクリック

f:id:patorash:20190517231506p:plain
SYSTEMになっていたら、所有者の変更をクリックする。

f:id:patorash:20190517231855p:plain
自分のアカウント名orメアドを入力して、名前の確認をクリックする

f:id:patorash:20190517232154p:plain
アカウント名に下線が引かれて表示されたらOKをクリックする

f:id:patorash:20190518105014p:plain
「ProtectedRoots のセキュリティの詳細設定」に戻るので、[ 継承の有効化(I) ] をクリックする

f:id:patorash:20190518105420p:plain
Rootを削除する

そして、OSの再起動を行います。

再起動後、Chromeはてなブログにアクセスしたところ、全く問題なし!やっと普通にChromeを使うことができそうです!😊

VSCodeのRemote Developmentプラグイン登場

このGWで最高のWindowsでの開発環境を作るんだ!と息巻いておりましたが、MicrosoftさんがVSCodeのRemote Developmentプラグインを発表しました。正直なところ、以下のブログを読んでいただければもう話は終わりです。

crieit.net

連休最後なのでとりあえず試してみるかーと思って試してみました。

試してみる

現在のところは、このプラグイン自体がベータ版のため、VSCode Insiders版でしか動かないので、VSCode Insiders版をインストールしました。

とりあえず、vagrant upした状態で、SSHの接続情報を出力させます。ユーザ名のところをusernameにしてますのでご注意ください。

PS > vagrant ssh-config
Host default
  HostName 192.168.100.2
  User vagrant
  Port 22
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile C:/Users/username/sources/github.com/patorash/ansible-provisioning-ubuntu-master/.vagrant/machines/default/hyperv/private_key
  IdentitiesOnly yes
  LogLevel FATAL

VSCodeでCtrl+Shift+Pでコマンドパレットを開き、Remote-SSH: Connect to Host...を選択して接続先を表示します。ない場合、Configure SSH Hosts...が表示されるので、それを選ぶと、SSHの接続先設定ファイルを選ばされるので、私はC:\User\username\.ssh\configを指定し、上記の設定をコピペして保存しました。その後、再度Remote-SSH: Connect to Host...を行い、defaultに対して接続をすると、新しいVSCodeのウィンドウが開き、Vagrant上で動くUbuntuに接続完了です。

あとはコマンドパレットからOpen Folderでプロジェクトフォルダを開けばOK。 VSCodeのターミナルを開くと、接続先のUbuntuのターミナルが開きました。完璧です。

rails sして速度を計測してみる

VSCodeとは直接は関係ありませんが、SMBでの共有フォルダと、共有フォルダではないUbuntu上のディレクトリで、全く同じプロジェクトをrails sしてみました。springが効いた状態で、初回表示ではありませんのであしからず。何度かページを表示した平均です。

環境 時間
共有なし 0.9秒
共有あり(SMB) 5秒

こうなってくると、Windowsからファイル共有せずに、VSCodeのRemote Developmentプラグインでファイル編集したほうがサクサク開発できそうです😊やっぱりLinux上でDockerを動かすと全然違うのだな…。

Windows & Vagrant & Hyper-Vでイケてる環境は?

  • VSCode Insidersを入れてRemote Development プラグインを入れる
  • VagrantUbuntuなどを入れる
  • 仮想スイッチを作る(内部)
  • WinNAT設定を行う
  • VMにIPを設定する
  • フォルダ共有は不要

でいいんじゃないかと思います👍

やり方は前回のブログを参照のこと。

patorash.hatenablog.com

vagrantは必要?という気もしますが、VMへのSSH接続とか、プロビジョニングとかが容易になるので、使ってもいいんじゃないかなと思います。