nishio-dens's diary

Railsとかプログラミング関連の備忘録

ActiveRecord4, includes(eager load)にはめられる

メモ。

今仕事でおもいっきり苦しめられてる問題。 同じ問題にハマる人がでないよう、ここに書き留めておく。

同じ名前のテーブルを2回join後、片方のみincludesするとおかしくなる。

以下のようなテーブルがあるとして。

f:id:nishio-dens:20140420180750p:plain

以下のテストケース test_eager_load_fail_test で失敗。 Product自身が持っているcorporation_id とちがうcorporationがひもづいてしまう。 うむ。

Invalid Includes

BitbucketのPull RequestをテストするJenkinsプラグイン、「Bitbucket PullRequest Builder Plugin」をリリースしました

BitbucketのPullRequest(PR)をテストするJenkinsプラグインを書きました。以下のページでソースを公開中です。

Githubページ: https://github.com/nishio-dens/bitbucket-pullrequest-builder-plugin

Github Pullrequest Builder PluginのBitbucket版のようなものです。今のところBitbucketのBasic認証にしか対応してないです。

Bitbucket PullRequest Builder Pluginとは?

下記のようなBitbucket上のPullRequestに対して

f:id:nishio-dens:20140216013817p:plain

JenkinsがPullRequestをテスト、結果をコメントとして書いてくれるプラグインです

f:id:nishio-dens:20140216013827p:plain

再テストしてほしい場合は、

f:id:nishio-dens:20140216013822p:plain

「test this please」というコメントを書けばよいです。

前提条件

インストール方法

  1. http://doc.densan-labs.net/bitbucket-pullrequest-builder.hpi を落とす
  2. JenkinsのJenkinsの管理 -> プラグインの管理(ManagePlugin) -> 高度な設定(Advanced) -> プラグインのアップロードで、ダウンロードしたプラグインをアップロードしてください
  3. 再起動を忘れずに!

f:id:nishio-dens:20140216014048p:plain

設定方法

  1. 新しいジョブ作る
  2. ソースコード管理、でGitを選ぶ
  3. Repository URL は git@bitbucket.org:${repositoryOwner}/${repositoryName}.git と記述
  4. Branch Specifier には */${sourceBranch} と記述

f:id:nishio-dens:20140216013834p:plain

5 ビルドトリガはBitbucket Pull Request Builderを選択。あとは図のように設定

f:id:nishio-dens:20140216013847p:plain

6 Cron には Crontab形式で実行間隔を書いてください。例えば */5 * * * * だったら5分ごとになります。 SCMをポーリングとか定期的に実行、にチェック入れても動かないので注意。

7 BasicAuth にはベーシック認証用のBitbucketのユーザ名とパスワードいれてください

8 RepositoryOwnerとNameにはPR先のリポジトリのOwner名とリポジトリ名入れてください

9 後は普段通りビルド設定書いてください。例えばrspec走らせたかったら、ビルド -> シェルスクリプトに bundle exec rspecって書くとか。

10 ジョブ設定保存するのを忘れずに。

ちなみに、ビルド実行ボタン押しても失敗します。Bitbucket Pull Request Builderのcronで指定した時間ごとでしかジョブ動かないです。 実行結果はこんな感じ。

f:id:nishio-dens:20140216013840p:plain

あんまテストしてないです。人柱募集中。

Railsでパンくずリストを作るなら、breadcrumbs_on_railsがオススメ

RailsなWebシステムにパンくずを組み込むなら、breadcrumbs_on_railsがオススメです。 スマートな記述で簡単にパンくずが作れますし、カスタマイズも容易に行えます。

導入も簡単で、Gemfileに

gem "breadcrumbs_on_rails"

と記述し、bundle install するだけでOKです。

controllerには、以下のコードのように add_breadcrumb を追加するだけで、簡単にパンくずが生成できます。

class BlogsController < ApplicationController

  add_breadcrumb 'Home', 'http://densan-labs.net'
  add_breadcrumb 'NishioのBlog', :blogs_path
  add_breadcrumb '詳細ページ', :blog_path, only: [:show]

  def index
  end

  def show
    # add_breadcrumb 'ここにadd_breadcrumbを書いてもいいよ', :blog_path
  end
end

add_breadcrumb の第一引数にはタイトルを、第二引数にはpathを指定します。 only指定で特定のactionの場合にのみ、パンくずの要素を追加することもできます。

あとは、viewに render_breadcrumbs を記述して完成です。

<h1>詳細ページ</h1>
<%= render_breadcrumbs separator: ' > ' %>

<h2>テスト本文<h2>
ここに何か書きます

render_breadcrumbsには、パンくずのセパレータが指定できます。 上記コードを実行すると、以下のようなパンくずリストが生成されます。

f:id:nishio-dens:20130824232909p:plain

Breadcrumbs::Builderを利用して、パンくずリストをカスタマイズする

先ほどのパンくずリストは、

<a href="http://densan-labs.net">Home</a> > <a href="/blogs">NishioのBlog</a> > 詳細ページ > ここに何か書いてもいいよ

というHTMLが生成されていました。

ただ、実際のWebサイトでは、単に区切り文字 > だけのパンくずなんてありませんよね。

例えば、Twitter Bootstrapのパンくずリストを組み込みたい場合、

  <ul class="breadcrumb">
    <li>
      <a href="http://densan-labs.net">Home</a>
      <span class="divider">/</span>
    </li>
    <li>
      <a href="blogs_path">NishioのBlog</a>
      <span class="divider">/</span>
    </li>

    詳細ページ
  </ul>

みたいなHTMLを生成してほしいわけです。

そんな時は、自作のBreadcrumb::Builderを作成してやる必要があります。

まずはcustom builderを作成。例えば、lib/custom_breadcrumbs_builder.rb に以下のようなコードを記述します。

class CustomBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
  def render
    @context.render "/shared/breadcrumbs", elements: @elements
  end
end

app/views/shared/_breadcrumbs.html.erb には、以下のようなviewを作成します。

<% if elements.present? %>
  <ul class="breadcrumb">
    <% elements[0..-2].each do |element| %>
    <li>
    <% if element.path.present? %>
      <a href="<%= element.path %>"><%= element.name %></a>
    <% else %>
      <%= element.name %>
    <% end %>
      <span class="divider">/</span>
    </li>
    <% end %>

    <%= elements.last.name %>
  </ul>
<% end %>

上記コードが、パンくずを生成する部分です。

あとはrender_breadcrumbs に、作成したCustomBreadcrumbsBuilderを使ってパンくずを生成するよう、builder指定を追加します。

<h1>詳細ページ</h1>

<%= render_breadcrumbs builder: ::CustomBreadcrumbsBuilder %>

<h2>テスト本文<h2>
ここに何か書きます

これで完成です。以下のように表示されたら成功です。

f:id:nishio-dens:20130824232924p:plain

RailsでHighcharts(lazy_high_charts)を使って綺麗なグラフを描画する

RalisでWebアプリケーションを作っていると、時々綺麗なグラフが描きたくなる場合があります。 例えば、在庫管理のWebシステムを作っているとして、在庫数の推移をグラフで表示したいなーなんて思う事があるわけです。

そんなときはHighchartsがオススメです。 下図のような高品質なグラフを簡単に生成することができます。

f:id:nishio-dens:20130824175911p:plain

Highcharts自体はJavascriptで作られているので、どんな言語のWebアプリケーションにも組み込めます。 Railsなプロジェクトに組み込む際も、jsを駆使して直接Highchartsを使ってもよいです。 ただ、HighchartsをRailsで簡単に使うためのGem、lazy_high_chartsを公開してくれている方がいるので、今回はありがたくそちらを使わせていただくことにします。

lazy_high_charts導入

今回はruby-2.0.0p247 と rails4 な環境で導入してみます。

Gemfileに

gem 'lazy_high_charts'

と書いて、bundle installを実行しておきます。

その後、assets/javascripts/application.js に、以下の三行を追記します。

//= require highcharts/highcharts
//= require highcharts/highcharts-more
//= require highcharts/highstock

これで準備完了です。

lazy_high_chartsを使ってみる

試しに、在庫数の推移を表示するグラフを書いてみます。 controller内には下記のコードを記述します。

  def index
    category = [1,3,5,7]
    current_quantity = [1000,5000,3000,8000]

    @graph = LazyHighCharts::HighChart.new('graph') do |f|
      f.title(text: 'ItemXXXの在庫の推移')
      f.xAxis(categories: category)
      f.series(name: '在庫数', data: current_quantity)
    end
  end

あとは、viewに以下の一行を記述すれば、Highchartsが利用できます。

<%= high_chart("sample", @graph) %>

実行結果は下図のようになります。

f:id:nishio-dens:20130824180036p:plain

グラフの種類も、f.seriesにtype指定を追加するだけで簡単に変更できます。

例えば、円グラフを表示する場合は、以下のようなコードを書けばよいです。

def index
  data = [['DataA', 45.0],['DataB', 55.0]]

  @graph = LazyHighCharts::HighChart.new('graph') do |f|
    f.title(text: '円グラフサンプル')
    f.series(name: '在庫数', data: data, type: 'pie')
  end
end

f:id:nishio-dens:20130824180048p:plain

とても簡単にグラフが描けましたね。

より詳細な使い方は、lazy_high_chartsのドキュメント を参照してください。

どんなグラフが描けるのかを知りたかったら、Highchartsのデモサイト を参照してください。

便利なグラフ描画ライブラリなのですが、Highchartsは商用のプロジェクトで使おうと思うとライセンス費がかかります。(オープンソースなプロジェクトで利用する分にはライセンス費は必要ありません) ライセンス費については、http://shop.highsoft.com/highcharts.html を参照してください。

はてなダイアリーから、はてなブログへ移行しました

はてなダイアリーから、はてなブログへ移行しました。

移行理由

  • markdownが使えるから

はてなダイアリーは長文がとても書きにくかったです。 vim/emacsで適当に文章書いて、それをはてなダイアリーの編集画面に貼付けて、謎のはてな記法に書き直して整形ってのが、とにかくめんどくさい。

あまりに書きにくいもんだから、1年ほど前にjekyllに移行しようと思い、ブログ作ってみたものの( http://blog.densan-labs.net/ )、書いた物を確認するのが結構めんどくさかったりして、結局やめてしまいました。

投稿するのが面倒だと、blogもどんどん書かなくなってしまうような気がしたので、思い切ってはてなブログに移行してみました。

ダイアリーからブログの移行は、ボタンをポチポチ連打するだけで簡単にできました。 以前の記事も、あたらしいはてなブログの方にリダイレクトされるみたいです。

markdownが使えるだけで、ブログがこんなに書きやすくなるなんて。 ということで、これからどんどんブログ書いていきたいです。

Profilerを使わずに、SQL Server Expressに発行されたクエリを取得する方法

最近マイブームのEntity Framework。データベースマイグレーションなんかも簡単にできちゃうし、とても便利なフレームワーク(O/Rマッパー)です。
Entity Framework Code Firstに関する解説なんかも書いちゃったりしてます( http://densan-labs.net/tech/codefirst/ )。

O/Rマッパーはとても便利なものですが、どんなクエリをSql Serverに対して発行しているかをキチンと理解して使わないと、時々痛い目を見ます。例えば、EFを使ってデータをInsertするには、以下のようなコードを書きます。

using (var context = new DbContext())
{
    context.Models.Add(new XXXModel{ ... });
    context.SaveChanges();
}

単純にデータをSql Serverにインサートしたいだけなのに、実はこれ、Insert文を発行後、こっそりSelect文も発行してたりします。

Entity Framework4.3の段階では、性能面で問題のあるクエリがDBに対して発行されていることが多々あります。
どんなSql文が発行されているかを把握することはとても重要ですが、残念ながら発行しているクエリを簡単に確認することはできません。
(EFの場合、Selectクエリはデバッガ等で確認することは可能です)

こういった場合、普通はSql Server Profiler等を使ってDBに発行されたクエリを確認するのでしょうが、お金のない私はSql Server Expressしかもっていません
(もちろんProfilerなんていう高価なものはついてません)。
Visual Studio Ultimateを持っていれば、IntelliTraceという超便利なトレーサーが使えますが、そんな高価なもの恐れ多くて触ることすらできません。

なんとかSql Server Expressに発行されたクエリを確認できないものか。調べてみると。。。なになに、Sql Serverにはトレースフラグという機能があると。これを使えば、発行されたクエリを確認できそうです。

結論から言うと、トレースフラグ3605と4032をオンにすることによって、Sql Serverのエラーログに発行されたクエリが表示されます。
4032はSql Serverが受け取ったコマンドをトレースするためのフラグです。3605はそのトレース結果をエラーログに出力するためのフラグです。

4032フラグは、SqlServer起動時に設定しないといけません。なので、SqlServerを起動している場合は、まずはサービスから停止させておきましょう。(下図のように状態が開始、になっている場合はSql Serverが起動していますので、停止させましょう)

その後、トレースフラグ4032をONにした状態でSQL Serverを起動するために、コマンドプロンプトを管理者モードで開き、以下のコマンドを入力してください。

net start MSSQL$SQLEXPRESS /T4032

次に、SQL SMSでSQL Serverにログイン後、以下のコマンドを発行します。

dbcc traceon(3605, -1)

これで準備完了です。クライアントからSql Serverに向けてクエリを発行後、エラーログを見てみましょう。
(エラーログ出力先は環境によって違いますが、多くの方は C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\Log\ERRORLOG にあると思われます)

TEXT: の後に発行されたクエリが表示されてます。やりました!

Entity Framework Code Firstの解説記事を書きました

Entity Framework Code Firstの解説を書きました。
http://densan-labs.net/tech/codefirst/ で公開してます。

2012年8月5日現在、完成してるのは1〜3章までです。
中途半端な状態で公開しようかどうか悩みましたが、このまま公開しないでおくとお蔵入りになりそうだったので、思い切って公開してみました。
頑張って続きも更新していきます。間違いなどありましたら、バシバシ指摘していただけるとありがたいです。