ActiveRecordでサブクエリをLEFT JOINする

集計関数の結果を、一覧データに結合して表示したかったのだけれど、どうやればいいのか悩んでしまったので、メモとして残します。
結論を書くと、ActiveRecord::Relationからto_sqlで文字列としてサブクエリを取得して、joinsで繋げました。
Railsのバージョンは4.1.8, postgresqlでやってます。

例えば、ユーザーのコメント数をカウントし、コメントの多い順に並び替えるにはこうします。

comment_counts = Comment.group(:user_id).select("user_id, COUNT(id) AS comment_count")
users = User.joins("LEFT JOIN (#{comment_counts.to_sql}) comment_data ON users.id = comment_data.user_id")
# COALESCE関数で初期値を設定するようにした。
users = users.select("users.*, COALESCE(comment_data.comment_count, 0) AS comment_count").
            reorder("comment_count desc")

Arelでできるかと思ったんですが、複雑になったので、こちらのほうがわかりやすいかなと思いました。


パトランド紹介 その1

これは大都会岡山Advent Calendarの5日目の記事です。

前日は@ryosmsさんの大都会岡山を楽しむための用語集2014でした。
明日は@arisonjpさんです。

今年はないのかなと思っていた大都会岡山Advent Calendarですが、急に始まってしまい、なんか金曜日を全て私が埋める空気になったので埋めてしまいました。
伝えたいことはとくになかったのですが、@razonに

と言われたので、我が家(通称パトランド)を3週にわたって紹介していこうかなと思います。

ところでなんでお前の家の紹介なんだ?と思っている人もいるだろうと思うので説明しておきますと、我が家は先月の11月15日に完成しました。先月末までは前パトランドの退去で忙しかったのですが、ようやく落ち着いてきて、徐々に家具なども揃えていってる最中であります。今回は我が家の1階のこだわりの品3つを紹介します。

その1.ダイニングの照明

ダイニングの照明

ご覧ください、この輝き。この照明はかなり高かったのですが、うちの嫁のこだわりで入れました。キラキラ輝いているのは本物のスワロフスキーで、輝きが違います。現在、この照明に合うダイニングテーブルを探している最中で、なかなか見つかりません…(いいテーブルは高いから踏ん切りがつかないというのもありますが)。

その2.ユニデール

ユニデール

ユニデールとは蓄熱暖房機のことです。詳しくはユニデールのサイトを見てください。
簡単に説明しますと、この中にはレンガが大量に入っていて、それを電気料金の安い夜間に温めて、昼間にその熱を放熱するという経済的な暖房です。ファンが付いていて強制的に熱を出すこともできるので、じんわりと温かくてとっても気持ちいい温かさです。石油ファンヒーターだと、灯油を買う手間がかかったり、コストも高かったりします。また、エアコンだと、電気料金の高い日中に使うと電気代がとんでもないことになります(最近のエアコンは効率がいいので大丈夫という意見もある)。

11月下旬の頃は、家の中を半袖半ズボンでいても暖かいくらいで本当に快適だなーと思いましたが、ここ数日で急激に冷え込んできたときには、設定温度が低かったのか、肌寒かったので、過信は禁物ですね。あと夜間電力は安いとはいっても、結構な電気代の請求がきました。しかし、手間がないし、お部屋全体をじんわり温めてくれるので、もう手放せない状態です。

その3.ホシ姫サマ

CIMG3364
天井になにかがありますね。紐を引っ張ってみると・・・

CIMG3363

ジャジャーン!なんと物干し竿が出てきました!
これがホシ姫サマです。ホシ姫サマの詳細はホシ姫サマのサイトを見てください。
簡単に説明すると室内用のもの干し竿です。必要な時だけ出して、しまうことができます。これのおかげで天気に関係なく洗濯物を干すことができます。天井から竿を固定したものもあり、そちらのほうが安価でいいのですが、頭を打ったりしそうだし、嫁の身長を考えるとちょっと高すぎたりするかなと思い、高さを調整できるものにしました。干す段階になると、高いところに移動できるので、竿にぶつかる危険性もないですし、低くすれば小物を干す時に手元で洗濯バサミを扱えるので手がだるくなることもありません。

CIMG3360

ちなみにここは洗面所で、洗濯物を干すのと、その洗濯物をすぐに収納できる棚を作ってあるので、3畳くらいの広さがあります。奥の洗濯機で洗って、ホシ姫サマで干して、隣の棚にすぐ収納。Tシャツ、パンツ、靴下など、よく着るものはカゴに放り込んでおくだけなので、たたむ手間もなくなったし、めっちゃ便利です。

CIMG3361
これがホシ姫サマを降ろした状態。洗面所が広いので、干す時にも窮屈な感じはしません。

以上が、その1でした。

次週もお楽しみに!!


jquery-uiでラジオボタンの見た目を変えた際のテスト方法

見た目を小綺麗にするために、ラジオボタンをjquery-uiを使ってボタン風に変更したところ、テストが落ちました。理由は簡単で、jquery-uiを使うとラジオボタン自身が表示されなくなるからですね、はい。

choose 'ほげ'

chooseが使えなくなるから、あかんなーと思って書き直したのがこちら。

# labelが「ほげ」の要素をクリック
page.execute_script %($('#hoge_1').trigger('click'))

これだとうまくいったけれど、テストが若干面倒になった。悩ましい。


SQLで時間帯検索を行う方法

postgresqlで時間帯検索を行いたかったのでやり方を調べたので備忘録として残す。
時間帯検索ってのは、例えば9時から18時までの日々のデータを取る、というものだ。

例えば、9時から18時までにユーザー登録されたユーザーを抽出したかったら、こうだ。

SELECT * FROM users WHERE TO_CHAR(users.created_at, 'HH24') BETWEEN '09' AND '17';

そして、これをRails風にしたかったので、以下のようにscopeで定義した。

class User < ActiveRecord::Base
  scope :only_office_hours, lambda { |from='09', to='17'| where("TO_CHAR(#{self.table_name}.created_at, 'HH24') BETWEEN ? AND ?", from, to) }
end

すっきり解決できたのでよかった。


ESET Smart Securityでmemcachedにアクセスできるようにする

Macのウィルス対策ソフトであるESET Smart Securityですが、これを使ってRailsで開発してると、memcachedにアクセスできなくなってしまいました。
キャッシュが効いて速度が向上するかチェックしたいのに、これは困る…。ということでファイアウォールの設定を修正したので、その設定を書いておきます。

まずはESETの詳細設定画面を開き、ネットワークをクリックします。
ESET Smart Securityの詳細設定画面でネットワークをクリック

次に、ファイアウォールのルールを追加します。
ファイアウォールのルールを追加
あとはmemcached用のルールを追加します。
名前は適当に。
ルール名を設定する

ルールは許可で内向きに設定します。
ルールは許可で内向きに設定

プロトコルはTCP、ポートはローカル、ローカルポートは変更していなければ11211にします。
プロトコルはTCP、ポートはローカル、ローカルポートは変更していなければ11211に

宛先をインターネット全体に設定します。
宛先はインターネット全体に

宛先をローカルネットワークとかでも大丈夫かなと思っていたのですが、どうもダメでした。IPアドレスで127.0.0.1に設定してもダメだったので、当面はこれが正解なのかなと思います…。