GitHub Pages を使い始めたこと
ブログが増え(て)ました。
理由:いつも使っているエディタ(自分の場合はVim)で日記が書きたかった。
あまりにもテキストエリアでの文章編集(とはてな記法)が身につかないので、いかに日記を楽に書くかを追求する予定。まずは、ターミナルから簡単に記事を書くためのツールをつくった。$EDITORを使ってターミナル上で記事を編集・プレビュー・公開までできるCUI向けツール。
GitHub - hibariya/retter: A diary workflow for shell users
さて、ご存知の方も多いと思いますが、世の中には Octopress という素晴らしいツールがあります。僕はRetterの開発途中でOctopressの存在に気づいてしまった。*1
作ってしまったものは仕方がないし、どこまでのものを作ることができるかも試したいので、しばらくは黙々と開発を続けようと思います。パッチなどは小さなものから大きなものまで受け付けております。
*1:もちろんRetterにも優れている点があります。このツールはretterというコマンドで操作するのですが、コマンド自体は片手だけで打ててしまうため、とても指にやさしいです。
Rails勉強会@東京第63回でセッションオーナーというのをやったこと
ここ数ヶ月間、行こう行こうと思いつつ中々いけなかった Rails' Wiki - Rails勉強会@東京第63回 に行ってきた。今回は RubyKaigi Advent Calendar 2011 | 日本Ruby会議2011(7月16日〜18日) のイベントのひとつでもあるのでした。
久々の参加で遅刻したんですが、着いて早々に [twitter:@takkanm] さんに「Rails3.1のセッションもって」と指名された。こういうイベントで長時間話した経験は無いし、何をやるべきなのかぼんやりとしか分かっていなかったので、結構困惑した。その時点で最新のRailsすらマシンに入れて無かったし、話せることは全くない気がしていたのでした。
だけど心配はいらなかった! 今回は状況がよかった(みんな割と詳しかった、他)のもあると思うけど、事前に入念な準備が必要なわけではないし(あるに越したことはないけど)、知らないことがあるとむしろそれをトピックにできたりして、セッションオーナーというのはとても好都合な立ち位置なのでした。周りの人とだいたい同じような立ち位置のままで、ききたいことがすぐきけるし話に入りやすい。そうやって周りの人に身を任せてお喋りするのは割と楽しい。
セッションオーナーという名目があるとお喋りするのが当然になって、イベントに参加している感がとても出てくるようなので、寂しがり屋でシャイでものぐさな人にはとても合っているのではないかと思いました。
決してうまくやれた訳ではないけど好い経験になった。
あと、そのとき教えてもらった RailsCasts on Apple Podcasts はとても便利そうだと思いました。
Mongoid::Paranoiaで論理削除したドキュメントも一緒くたに問い合わせる
hatena.vimの動作確認も兼ねて。
unscoped で論理削除されたものも引っ張ってこれるかと思ったら違った。
# mongoid-2.0.2/lib/mongoid/paranoia.rb <中略...> module ClassMethods #:nodoc: # Override the default +Criteria+ accessor to only get existing # documents. Passes all arguments up to +NamedScope.criteria+ # # Returns: # # A +Criteria+ for deleted_at not existing. def criteria(*args) super.where(:deleted_at.exists => false) end # Find deleted documents # # Examples: # # <tt>Person.deleted</tt> # all deleted employees # <tt>Company.first.employees.deleted</tt> # works with a join # <tt>Person.deleted.find("4c188dea7b17235a2a000001").first</tt> def deleted where(:deleted_at.exists => true) end end <中略...>
Mongoid::Paranoiaを使うとcriteriaが上書きされるんですね。だから unscoped とかしてもだめだったのか。
削除されたものは deleted で取れるけど、論理削除関係なく問い合せたいときはどうするんだろう。
module Mongoid::Paranoia::ClassMethods def with_deleted c = criteria c.selector.clear c end end
足してその場をしのいだ。
はっとしたこと
ruby-1.9.2-p0 > 10.times.map{ 'foo' }.map{|v| puts v.object_id } 2152510320 2152510280 2152510200 2152510160 2152510120 2152510060 2152510020 2152509980 2152509920 2152509780 => [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil] ruby-1.9.2-p0 > (['foo']*10).map{|v| puts v.object_id } 2151828140 2151828140 2151828140 2151828140 2151828140 2151828140 2151828140 2151828140 2151828140 2151828140 => [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
あまり意識してなかった。
http://doc.ruby-lang.org/ja/1.9.2/class/Array.html
数値とかSymbolはどちらも同じでobject_idは変わらない。少し前にRHGをさらっとだけ読んだのでこれは想像できた。
ruby-1.9.2-p0 > 10.times.map{ :urryyyy }.map{|v| puts v.object_id } 498728 498728 498728 498728 498728 498728 498728 498728 498728 498728 => [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]
予想があたってよかった。
Fabricationを使ってみた
※2011/11/08 コメント欄で指摘を頂いた箇所を加筆修正しました。また、割と古い記事ですので最新の情報は Fabrication を参照することをお奨めします。
これを作ってるとき、machinistとmachinist_mongoを使っていたんですが、試しに前々から気になっていたFabricationで書き換えてみました。README書いてあることをいくつか実際にやってみたのでメモしておきます。割と使いやすかったです。
何に使えるの
下記をサポートしてるそうですので、Mongoid使えます。やった!
- Plain old Ruby objects
- ActiveRecord objects
- Mongoid Documents
使ったもの
- Fabrication…本日のメイン
- Faker…嘘データをどんどこ作ってくれるやつ
QuickStart & 使い方
Gemfile
Rails/Mongoid/RSpec/Fabricationで↓のような組み合わせで使ってます。
group :development, :test do gem 'rspec-rails', '>= 2.0.0.beta.22' gem 'mongoid-rspec' gem 'faker' gem 'fabrication' # <= これ gem 'wirble' gem 'spork' end
記述する場所
spec/fabricators.rbに書くか、spec/fabricators/*.rbに複数ファイルにして書いてもいいみたいです。ここに置いておけば、必要になったら勝手に呼ばれます。最初から自分で読み込んでおきたいときはspec/spec_helper.rbなどに書きます。
Fabricatorを書いて使ってみる
spec/fabricators.rbなどにfabricatorを書いていきます。blueprintみたいな感じで。
# Userモデルはこんな感じだとします class User include Mongoid::Document field :screen_name, :type=>String field :description, :type=>String field :site, :type=>String field :gender, :type=>String end # Userモデルのfabricatorを作ります Fabricator(:user) do screen_name { Faker::Internet.user_name } description { Faker::Lorem.paragraph[0..190] } site { ['http://', Faker::Internet.domain_name].join } gender { ['male', 'female'].sort_by{ rand }.first } end
作ったFabricatorをspecの中で好きなときに呼び出します。factorygirlやmachinistと同じように、3通りの呼び出し方があります。
# インスタンスを保存して返す Fabricate(:user) # => #<User _id: 4cb18e0c011c0e5a2c000001, screen_name: "aidan", description: "Vel iste illo beatae maxime earum accusantium. Facilis doloremque nemo dolores perspiciatis. Eum et nisi sunt qui soluta facilis consequatur quasi. Qui sunt omnis beatae sit. Quisquam earum d", site: "http://wintheiserwunsch.com", gender: "female"> # インスタンスを保存せずに返す Fabricate.build(:user) # => #<User _id: 4cb18e32011c0e5a2c000002, screen_name: "darlene", description: "Exercitationem voluptatem voluptatibus officia saepe labore earum. Voluptas ut ipsam soluta. Libero possimus eius illo soluta quo blanditiis quod. Similique ea qui reprehenderit nihil ut cons", site: "http://schiller.uk", gender: "female"> # 属性だけを生成してHashで返す Fabricate.attributes_for(:user) # => {"screen_name"=>"jaylon", "description"=>"Et vitae nobis enim non. Quia sunt ipsum laboriosam. Maxime ut neque voluptatum velit est aliquam sequi qui. Eius dolorem id ut assumenda.", "site"=>"http://wuckert.uk", "gender"=>"male"}
Fabricatorの継承とか
すでに作ったのとはちょっと違うのがほしいときは、すでにあるfabricatorを継承することができます。:fromパラメータに継承元の名前を入れて、変更したいフィールドの定義を記述します。
# 必ずfemaleなひとがほしい Fabricator(:female, :from=>:user) do gender 'female' end
もちろん、継承は使わず呼び出すときに直接指定することもできます。
# いまだけfemaleなひとがほしい Fabricate(:user, :gender=>'female') # => {"screen_name"=>"daron", "description"=>"Aut dolor reprehenderit consequuntur nihil magni odit eveniet. A est magni nam vero praesentium. Praesentium quae perferendis mollitia. Voluptatem harum ex aperiam tempora ab nihil voluptas. ", "site"=>"http://huel.com", "gender"=>"female"}
クラスの明示的な指定
:class_nameパラメータで明示的にクラス名を指定することもできます。色々なパターンでFabricatorをつくりたいときなどはこれで。クラス名はシンボルやklass、文字列で指定できます。
# :class_name は :user, User, 'User' などで指定可 Fabricator(:invalid_user, :class_name=>:user) do screen_name 'hibariya' description 'i have no gender' end
Sequenceで一意にする
MachinistのShamのようなものも用意されています。*1Fabricate.sequenceを使うと、呼び出すたびにインクリメントする数値が得られます。ブロックも渡せるので数値以外の一意な何かもつくることができます。Fakerには大量の単語とかがコード中にドカっと入ってるんですが、普通に重複しますので、データが一意でないといけないときなどはこれを使います。
大きく分けると3つの書き方になるようです。
Fabricate.sequence(:foo_id) # 呼び出すたびに0から始まる連番を返す Fabricate.sequence(:bar_id, 1000) # 呼び出すたびに1000から始まる連番を返す Fabricate.sequence(:future){|n| n.days.since } # 呼び出すたびに1日ずつ未来の日付を返す
さっきのUserモデルの例だとこんな感じになります。
# uriもscreen_nameも重複させたくない! Fabricator(:user) do screen_name { Fabricate.sequence(:screen_name){|i| [Faker::Internet.user_name, i.to_s].join } } # <= ここ description { Faker::Lorem.paragraph[0..190] } site { Fabricate.sequence(:uri){|i| ['http://', i.to_s, Faker::Internet.domain_name].join } } # <= ここ gender { %w(male female).sort_by{ rand }.first } end
on_init, init_with でnewに引数を渡す
newするのに引数が必要なクラスのfabricatorを作るときなどに使えます
class Site def initialize(uri) @uri = uri end end # on_initとinit_withで、initializeに渡す引数を指定できる Fabricator(:site) do on_init{ init_with(['http://', Faker::Internet.domain_name].join) } end
after_build, after_create コールバック
保存する前、保存したあとのコールバック。さっきまで勘違いしていたんですが、Fabricate.buildでもafter_createは呼ばれるようです(でもsaveはされない)これはバグだったそうです(https://github.com/paulelliott/fabrication/pull/36
)。
# User#fetch_recent_entries!がsave前のステップで呼び出される Fabricator(:foo_user, :from=>:user) do after_build {|user| user.fetch_recent_entries! } end # User#fetch_recent_entries!がsave後のステップで呼び出される Fabricator(:bar_user, :from=>:user) do after_create {|user| user.fetch_recent_entries! } end
belongs_to, references_oneな関連を!で表現
belongs_to, references_oneな関係にあるものは!を付けると自動的に作ってくれるらしい。べんり!というのは間違いで、!を付けるか否かで関連が作られるタイミングが変えられるようです(!を付けなければ参照されるまで作られない)。
Fabricator(:umbrella) do color { %w(red green blue pink violet purple).sort_by{ rand }.last } end Fabricator(:girl) do name 'unknown' umbrella! # !を付けると即座に関連が生成される end
Machinist <=> Fabrication 比較表
Machinistとの違いを、よく使う項目だけ表にしてみるとこんな感じでしょうか。*2
Machinist | Fabrication |
---|---|
Model.blueprint do ~ end | Fabricator(:model) do ~ end |
Model.blueprint(:named_blueprint) do ~ end | Fabricator(:named_fabricator, :from=>:model) do ~ end |
Model.make | Fabricate(:model) |
Model.make_unsaved | Fabricate.build(:model) |
Model.plan | Fabricate.attribues_for(:model) |
よく更新してるブログを上の方に表示する「RSSS」を作ったこと
詳しくは: http://rsss.be。使うと↓のような感じになります。
http://rsss.be/hibariya
これはなに
- 使っているブログをまとめて登録できるプロフィールのようなもの
- 最近よく更新しているブログを大きく上の方に表示する
- 最近どのブログをよく更新していたかの推移を表示する
- 使っているブログのフィードをまとめて吐く
- フィードを吐くサービスならブログでなくても可
- Twitter OAuth(Read権限)でログインする必要あり
自分に関連してるURLをがーっと並べるタイプのプロフィールとかで、あまり使わなくなったサイトを一覧から消したりして管理するのが面倒だなーと思ってたのが作るきっかけです。最近あのミニブログ使ってないなとか、最近リブログしかしてないなーとかそういうのがぱっと見で分かるようなページが欲しかったので、HerokuとRails3とMongoDBの勉強を兼ねて作ってみた*1。最近Herokuがどうのこうのというエントリが多かった原因はこれでした。
しばらくここで開発中 GitHub - hibariya/rsss: 最近使っているサービスを可視化
HerokuでRuby1.9.2が使えるようになってる
今更ですが、使えるようになってましたの記録。
% heroku stack aspen-mri-1.8.6 * bamboo-ree-1.8.7 bamboo-mri-1.9.1 (beta) bamboo-mri-1.9.2 (beta) % heroku stack:migrate bamboo-mri-1.9.2
試しに使ってみたところ、Herokuで使うRubyを1.9.1から1.8.7に戻した - のどをRubyでいっぱいにしてで悩んでいたいくつかの悩ましい事象も起こらず、普通に使えています。ところで(beta)なのはいつまでなんでしょうね。