インスタンス概要
タイトルにもあるように、Tor の Hidden Service に対応してます。*1
普通のドメインもあるので、 Tor を使わない人はこちらをどうぞ。
どんな人向けか
- 投稿元IPを隠してトゥートしたい人
- そんな人が投稿する内容を見たい人
- トゥートのリンクを安易に踏んだりしない人
など。
今後やりたいこと
Tor ユーザーだけに表示されるトゥートとか作りたい。
*1:というか、これに時間がかかっていたわけですが
技術書典は書く側で参加したい気持ちはあるけど、書くネタと書く時間があるかどうか…
— 神速@リリカルエンジニア (@sinsoku_listy) 2017年4月9日
あー、自分の知ってるRailsアンチパターンとか書きたいかも。自分の犯した罪(アンチパターン)を贖罪したい…。
— 神速@リリカルエンジニア (@sinsoku_listy) 2017年4月9日
技術書典2 に行ったら無性に本を書きたくなったけど、本書くのは 面倒 大変です。
というわけで、とりあえずブログに記事を1つ書いてみた。
factory_girl はテスト用データを作成するときに使う gem です。
下記は User のモデルを定義するファクトリーです。
FactoryGirl.define do factory :user do first_name "John" last_name "Doe" admin false end end
このファクトリーから User のテストデータを生成することができます。
FactoryGirl.create(:user) #=> #<User id: 1, first_name: "John", ...
factory_girl
は関連先のレコードを自動生成したり、連番を生成したり、結構多機能だったりします。
このあたりの詳細を知りたい方は公式の README を読むか、英語が苦手なら日本語の紹介記事などを読むと良いです。
ここからが本題で、factory_girl
で定義したファクトリーは時間が経ったり、作成者が未熟だと 錆びる (=ビルドしづらい、できなくなる)ことがあります。
錆びついたファクトリー例を紹介してみたいと思います。
class User validates :nickname, uniqueness: true end FactoryGirl.define do factory :user do nickname "sinsoku" end end
これはひどい。 uniqueness 制約により2回目のビルドは失敗します。
FactoryGirl.define do factory :user do sequence(:nickname) { |n| "nickname_#{n}" } end end
上記のように sequence を使って回避すべきです。
クラスの属性だけでテストができる( DB アクセスが不要な)ケースがあります。
class Book def published? published_at <= Time.current end end
このようなメソッドのテストでは DB アクセスをしないように build_stubbed
を使うべきです。*1
しかし、ファクトリーが下記のような定義だとレコードが生成されてしまいます。
FactoryGirl.define do factory :book do author { create(:user) } published_at '2017-04-10' end end
これは association を使って定義すべきです。
FactoryGirl.define do factory :book do association :author, factory: :user published_at '2017-04-10' end end
association を使うことで、 build_stubbed
の時にレコードが生成されなくなります。
FactoryGirl.define do factory :user do name 'serval' transient do friends_count 10 end after(:create) do |_user, evaluator| create_list(:user, evaluator.friends_count) end end end
デフォルト値のフレンズが多すぎます><
FactoryGirl.define do factory :user do name 'serval' factory :user_with_friends do transient do friends_count 10 end after(:create) do |_user, evaluator| create_list(:user, evaluator.friends_count) end end end end
デフォルトのファクトリーはシンプルに保ち、フレンズの多いファクトリーは別にしておきましょう。
class Servant belongs_to :master validate :must_be_valid_master TEAM = { 'Artoria Pendragon' => 'Shirou Emiya' } private def must_be_valid_master errors.add(:master, ' is invalid') unless TEAM[name] == master.name end end FactoryGirl.define do factory :servant do association :master, factory: :user name 'Artoria Pendragon' end end
このファクトリーは master が ‘Shirou Emiya’ のときだけビルドできます。
user = FactoryGirl.create(:user, name: 'Shirou Emiya') servant = FactoryGirl.create(:servant, master: user)
このように、ビルド時に必要な関連を渡すようなファクトリーは使いづらいです。
FactoryGirl.define do factory :servant do association :master, factory: :user, name: 'Shirou Emiya' name 'Artoria Pendragon' end end
FactoryGirl.create(:servant)
だけでビルドが出来るようにしておくべきです。
時間の経過によりバリデーションが追加・変更されたり、モデルの関連が変わってしまい、ファクトリーが錆びてしまうことがあります。
幸い factory_girl
には Lint がついています。
# lib/tasks/factory_girl.rake namespace :factory_girl do desc "Verify that all FactoryGirl factories are valid" task lint: :environment do if Rails.env.test? begin DatabaseCleaner.start FactoryGirl.lint ensure DatabaseCleaner.clean end else system("bundle exec rake factory_girl:lint RAILS_ENV='test'") end end end
上記のような rake タスクを作成し、 CI で常にファクトリーがビルドできるかチェックしておくのが良いでしょう。
パッと思い出せた factory_girl
に関するアンチパターンを書いてみました。
他のアンチパターンはやる気と時間があれば書く…かも?
*1:無駄なレコードを生成するとテストが遅くなってしまいます。
CircleCI 2.0 が使えるようになっていたので、アップグレードしておいた。
今まで circle.yml
だったけど、 .circleci/config.yml
に変わっている。
Ruby の設定例は Language Guide: Ruby があるので、これを参考にすると良い。
version: 2 jobs: build: docker: - image: ruby:2.4.0 - image: postgres - image: redis environment: PHANTOMJS_URL: https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 working_directory: ~/workspace steps: - checkout - type: cache-restore key: phantomjs-2.1.1 - type: cache-restore key: gemfile-{{ checksum "Gemfile.lock" }} - run: | which phantomjs && exit curl --location --silent $PHANTOMJS_URL | tar xj -C /tmp --strip-components=1 mv /tmp/bin/phantomjs /bin - run: apt-get update -qq && apt-get install -y build-essential nodejs - run: bin/setup - run: rake - run: yard -o doc - store_artifacts: path: doc destination: doc - type: cache-save key: phantomjs-2.1.1 paths: - /bin/phantomjs - type: cache-save key: gemfile-{{ checksum "Gemfile.lock" }} paths: - /usr/local/bundle
注意点は デフォルトだと bundler の cache が効かない とか、 PhantomJS が入っていない とかくらい?
Language Guide: Ruby
の例に合わせて db:create db:schema:load
を実行して db:migrate
を実行しない方が少し速くなると思う。
ただ、 bin/setup
が動作するのをチェックしたくて CI で毎回動かすようにしている。
Rakefile
に下記のような定義をしていて、 rake を実行すると rubucop + parallel:spec が動くようにしている。
# frozen_string_literal: true # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. require File.expand_path('../config/application', __FILE__) Rails.application.load_tasks unless Rails.env.production? require 'rubocop/rake_task' RuboCop::RakeTask.new task(:default).clear task default: [:rubocop, 'parallel:spec'] end
Using docker-compose や background を使えば、もうちょい改善とか実行速度アップとかできるかも?
まぁ、そのあたりは時間あるときに試す。時間あるときに。
前々から Rust の良いと聞いていたので、ちょっと入門してみた。
Rust に入門した https://t.co/UfBJ6c1i9C
— 神速@リリカルエンジニア (@sinsoku_listy) 2017年2月27日
公式の プログラミング言語Rust が分かりやすそうなので、これを見ながら最初の “Hello, World” まで進めた。
まぁ、環境構築しかやってないってことですね。
このコミットの通りで、 Docker を使って Rust の環境を構築した。
新しい言語を触る場合、環境構築のどこでハマるか分からんので、 docker コンテナ使う方が楽。*1
3日坊主にならないように、定期的に Rust 触ってブログに書きたいですね。そんな気持ちはあります。たぶん。
*1:ローカルで変な問題踏んだりとかもしないし
2/18(土) と 2/25(土) に Speee さんのもくもく会に参加して、 gem が出来たので紹介。
bundler_diffgems は bundle update
を支援するための CLI ツールで、GitHub の比較URL を簡単に表示できます。*1
$ gem install bundler_diffgems
でインストールできます。
いつものように bundle update
をします。
$ bundle update
そのあと、 bundle diffgems
を実行します。
$ bundle diffgems rake: 11.3.0 => 12.0.0 - https://github.com/ruby/rake/compare/v11.3.0...v12.0.0 rspec: 3.5.0 => ...
こんな感じで GitHub の比較URL付きでアップデートされた gem の一覧が表示されます。
GitHub API の実行は parallel の gem を使っているので、そこそこ実用的な速度で比較URLが出るんじゃないかなーと思います。
Pull Request で見やすくするために md_table
というフォーマットだけ増やしてます。
私はこんな感じのスクリプトを bin/update_gems
に保存して、使っています。
#!/bin/bash set -e # TODO: You need to edit these variables REPO=owner/repo BASE_BRANCH=master if [ -z "${GITHUB_TOKEN}" ] then echo 'usage: GITHUB_TOKEN=<your 40 char token> update_gems' exit 1 fi # Update gems bundle update # Push a commit NOW=$(date +'%Y%m%d%H%M%S') HEAD_BRANCH="gems/${NOW}" BODY=$(bundle diffgems --escape-json -f md_table) git checkout -b ${HEAD_BRANCH} git add -u git commit -m "Update gems ${NOW}" git push origin ${HEAD_BRANCH} # Create a pull request API_URL="https://api.github.com/repos/${REPO}/pulls" echo '{ "title": "Update gems '"${NOW}"'", "head": "'"${HEAD_BRANCH}"'", "base": "'"${BASE_BRANCH}"'", "body": '${BODY}' }' | curl -H "Authorization: token ${GITHUB_TOKEN}" -X POST --data-binary @- ${API_URL}
CI で上記のスクリプトを実行すると定期的な bundle update
が実現できます。
下記は AWS CodeBuild の buildspec.yml
の例です。*2
version: 0.1 phases: pre_build: commands: - gem install bundler - gem install bundler_diffgems - git config user.name bundler_bot - git config user.email mail@example.com build: commands: - ./bin/update_gems
gem のアップデートを定期実行していない人でも便利に使えると思うので、ぜひお試しください。
*1:compare_linkerに似てる
2/11(土) に 名古屋Ruby会議03 に参加してました。
会場が大須演芸場ってこともあり、他のイベントと雰囲気が異なっていてとても良かったです。 #nagoyark03 を見ると雰囲気がわかると思います。
発表者の口調もなんか落語っぽい感じになっていたり、2階でお酒飲みながら発表を聞いたり、なかなか出来ない経験が出来ました。
電源・ネットワークに関する設備が貧弱だったのは少しだけ気になった。
使える無線LANとか無かったようなので、私は自分の WiFi ルータを使っていたけど、他の人も同じように対応してたのかな。
「きっと何人かは遅くまで飲んでいるだろう」と思って、今回は宿の予約なしで参加していました。
名古屋Ruby会議は宿とってないので、朝まで誰かと飲む || 宿に泊まる || ネカフェで適当に過ごす を OR で評価する予定です
— 神速@リリカルエンジニア (@sinsoku_listy) 2017年2月8日
朝近くまでお酒飲みながら技術の話をするのはやっぱり楽しいですね。 自分が知らない技術的な話題、考え方なども聞けて、かなり有意義だった。
ただ、翌日日曜の予定も潰れるのでオススメはできない。
#nagoyark03 ぺろぺろ - Github pull request bot framework - https://t.co/AOvHdLgyGz
— mzp (@mzp) 2017年2月11日
mzp/prpr に前々から secret token のチェックについてプルリクを投げたかったので、この機会にプルリクを投げておいた。
東京にも帰り着き、プルリクも作り終わったので、これで私の #nagoyark03 は無事に終わりました。
朝早くから準備されていたスッタフ、発表者の方々お疲れ様です。
ありがとうございました!
転職DRAFT は友達を紹介する(もしくは紹介される)とオライリー本が貰えます。
ただ、7月くらいに 友達の紹介 で登録して、更に8月に 友達を紹介 したのですが、まだ1冊しか頂けていない。
TOP に紹介キャンペーンについては書かれています。
ただ、ここにはオライリー本の発送時期については 明記されていません 。
以下、メールの全文。
いつもご利用いただきありがとうございます。 転職ドラフト運営事務局でございます。 友達紹介成立の件でご連絡させて頂きました。 この度はお客様にはお手数をおかけし、誠に恐れ入ります。 sinsoku様の友達紹介は仰るとおり現在合計【2件】成立しております。 但し2件目の友達紹介は第二回転職ドラフト終了後の8/1に成立しておりました。 その為、2件目の書籍は第三回転職ドラフト終了後に贈呈させていただく形となります。 その為、誠に恐れ入りますが、今回は頂いた本のタイトルの中から、 今回欲しい本を【1冊】だけお選びいただけないでしょうか。 2冊目の書籍につきましては、第三回転職ドラフト終了後に改めて贈呈させていただければと存じます。 この度は友達紹介の贈呈日のルールが分かりにくい形だったかと存じます。 この度はsinsoku様にはご迷惑をおかけし、誠に申し訳ございませんでした。 今回のことを受け、より分かりやすいルールとなるよう改善させていただければと存じます。 本件につきまして、何卒宜しくお願い致します。
締切のシステムがよく分からないけど、なんか締切を過ぎてたらしい。
ただ、第三回転職ドラフト終了して1ヶ月くらい経つけど、連絡は特にない。*1
大した額のものじゃないので正直どうでも良いけど、リブセンスが書籍の発送状況の管理をどうやってるのか気になるなーと思いました。
今どきメールで書籍タイトルの返信を要求してくるようなサイトなので、担当者によるスプレッドシート管理とかなのかな。
*1:4ヶ月前の話なので完全に忘れてました