TIM Labs

Rails のバリデーションには特定のコンテキストのときだけ実行させることができる on オプションが存在している。

validates :field1, presence: true
validates :field2, presence: true
validates :field3, presence: true, on: :admin

こうすると、 valid?(:admin) のときだけは全てのフィールドが必須入力となるが、そうでない場合は field1field2 のみ必須となり、 field3 は任意入力になる。なるほど、便利だ。

ところが、これを逆転させたいとき、即ち :admin コンテキストのとき「だけ」field3 を任意入力にしたいとなると、途端に面倒なことになる。

validates :field1, presence: true
validates :field2, presence: true
validates :field3, presence: true, on: [:create, :update, :context_foo, :context_bar]

おおう。これ、 :context_baz が増えたら、ここもメンテナンスせなあかんのか? ちょっとそれはなくない? このコードからは「:admin コンテキストの時だけ任意入力」という意図が全く読み取れない(そもそも :admin が出てこないではないか)ので、適切にメンテナンスするのは無理がある。

問題

前回、新人研修の一環として「オセロの実装」を課題として設定したものの、 設定した当人が実装できないようでは話にならないので頑張って実装しました (一人二役で指す寂しいゲーム編 / 遅延評価編 / 仮AI作成編 / 本格AI作成編 / AI高速化編 / AI vs AI編)。

これはこれで楽しかったものの、良くも悪くもオセロですから、 寝るのも忘れて遊びたくなるものかと言われるとそういうものではありませんでした。

どうせならもっとエキサイティングでキュートなゲームを実装してみたいものです。 何か良い題材はないものでしょうか。

問題

昼のお仕事はC#で、 夜のお仕事はRubyで書いていると、 「あっちでできることはこっちでどう書くんだっけ」 と立ち止まることが度々あります。

その都度リファレンスを引けば分かることではあるのですが、 何度も引き直しているとさすがに面倒臭くなってきます。 特にシーケンス処理は言語毎に微妙に差異があって、 注意してないと妙なバグを埋め込むことになりかねません。 どこかに良い感じのシーケンス処理API比較表が転がっていないものでしょうか。

他人の開発画面、覗いてみた事ありますか。

覗いてみた事が無い方は、是非見せてもらってください。意外と面白いですよ。 gitのコミットの仕方ひとつとっても、人によって全く違うんだなと思うはずです。

git使いが10人いれば、使い方も10通りなんだなと、他人のコンソール覗きこむたびに感じます。

私の場合、プロジェクトが数ヶ月から半年に一度変わる(または並行して複数のプロジェクトに入る)という事が多く、いろんなgit使いの方に触れる 機会が多いです。

コンソール上でgitを操作する人、SourceTreeやEclipseプラグイン等のGUIツールで操作する人、git rebaseを多様する人、全くしない人、コミットグラフが綺麗な人、汚い人(そもそもあんまりこだわりを持っていない人?)、コミットメッセージを日本語で書く人、英語で書く人。。。

私は、「git pull」というコマンドを使う事はほぼ無いのですが、たぶんそういう情報は私の開発画面じーっと覗き込んでないと知りえない事だと思います。 gitを長い間使っている方は、自分流のgitの使い方を持っているかと思います。

今回は私のローカルでのgitの使い方を晒してみます。

ちょっと記事が長くなってしまいました。以下、今回の要点を最初に書いておきます。

  • コマンドは短く
  • 必要な情報は常に表示する
  • とにかくcommit
  • コミットコメントは一行で、かつ自分が分かりやすいコメントを
  • hookを活用する
  • 余計なものは無視する、または消す

その1 - その4 まで、Arelの内部構造について説明してきました。 魔法のような技術に思われるArelも、意外と単純な構造をしていました。

今回は、Arelの内部構造をGraphvizで出力する方法を紹介します。 図で構造を出力してみると、クエリがどういうノードで構成されているのかイメージでき、Arelへの理解がもっと深まるかと思います。

以下、目次となります。

今回はArelがjoinクエリを生成する過程を学んでみます。 使用するサンプルコードは以下の通りです。

product = Arel::Table.new(:products)
corporation = Arel::Table.new(:corporations)
product_detail = Arel::Table.new(:product_details)

product
  .project('*')
  .join(corporation)
  .on(product[:corporation_id].eq(corporation[:id]))
  .to_sql
# "SELECT * FROM `products` 
# INNER JOIN `corporations` ON `products`.`corporation_id` = `corporations`.`id`"

product
  .project('*')
  .join(corporation)
  .on(product[:corporation_id].eq(corporation[:id]))
  .join(product_detail)
  .on(product[:id].eq(product_detail[:id]))
  .to_sql
# "SELECT * FROM `products` 
# INNER JOIN `corporations` ON `products`.`corporation_id` = `corporations`.`id` 
# INNER JOIN `product_details` ON `products`.`id` = `product_details`.`id`"

まずは、joinがどういう動きをするのか、から見ていきましょう。

以下、目次となります。

今回は以下のようなSQL生成の過程を学んでみます。

product = Arel::Table.new(:products)
product.project('*').where(product[:price].eq(1000)).to_sql
# "SELECT * FROM `products` WHERE `products`.`price` = 1000"

まずは

product[:price].eq(1000)

の部分から読んでみます。

以下、目次となります。

今回は、以下のような単純なSQLをarelで生成してみます。

select * from products;

Arelで書くと以下のようになります。

product = Arel::Table.new(:products)
product.project('*').to_sql # select * from products;

上記コードでなぜ select * from products; というsqlが生成されるのかを見ていきましょう。

以下、目次となります。

Rails3, ActiveRecordからは、内部でArelと呼ばれるSQL生成用のライブラリが利用されています。 今回、Arelが内部でどのようにSQLを生成しているのかを調査したので、当ブログにて公開いたします。 ちょっと長くなってしまったため、全5回に分割しました。

以下、目次となります。

みんな大好き、Excelの話題です。

Excelは万能です。本来表計算ソフトであるはずのExcelですが、プロジェクトのドキュメントがExcelなのはもちろん、帳票もExcel, 挙げ句スクリーンショットもExcelに貼付けられて送られてくるなど、ありとあらゆる場面で活用されています。本当やめてほしいです。

これだけ広く使われていると、お客様からExcelで読めるようなデータを出力してほしい! という要望もあるかと思います。業務システムの場合、Excelでのデータ出力は必須ではないか、とさえ思われます。

今回はExcelで開けるファイルを出力してほしいと言われた場合、Railsではどのように実装すればいいのか、について考えてみます。

最近のコメント