はてなブックマーク - Rails3 Arel ActiveRecord::Relation考察
    このエントリーをはてなブックマークに追加

    夏が過ぎ風あざみ。

    謎の首痛と腰痛、そして風邪に見舞われた8月でしたが、
    人にうつせば治るというもので、すっかりよくなった山本です。

    今日はRails3のコネタを。

    Arel

    Rails3では、O/RマッパーであるActiveRecordが進化を遂げ、「Arel」というライブラリを使用するようになりました。
    「Arel」については様々なサイトで解説が載ってますが、
    Rails2のfind系メソッドは、呼び出しの際にDBに対してSQLを発行していたのが、
    Rails3では、インスタンスは一旦、 ActiveRecordのサブクラスである、 Relationのオブジェクトとして格納されます。
    全部が全部ではないですが。

    例えば、Userモデルがあるとして、

    user = User.find(1)

    と、findを使ってデータを取得して、userの中身を見ると

    user.class
    => User(id: integer, email: string, .....created_at: datetime, updated_at: datetime)

    と、Userモデルのインスタンスになっていますが、

    user = User.where(:id => 1)

    と、whereを使うと、

    user.class
    => ActiveRecord::Relation

    となります。

    そしてこの時、SQLの処理は行われません。
    あくまで関係の定義が詰まっているだけ。

    この利点は、不要不急なSQL処理が走らないことですね。
    また、これこそが、whereを数珠つなぎにして条件を加える、メソッドチェーンの書き方ができるわけです。

    user = User.where(:id => 1)
    user = user.where("number  > 1")
    user = user.where("type  > 2")

    と書いて、3回もSQLが走ったら大変ですし。

    じゃあいつクエリが発行されるのかというと、
    実際に値を表示するときです。

    例えば、
    puts user

    user.all
    などと書いたときですね。

    本当に値が必要になったときに処理をしてくれるので、リソースの節約につながるのかなと。

    逆効果も

    ただ、使い方を誤ると逆に無駄にクエリを発行することにもなります。

    ある条件のデータの最大と最小を取り出したい、といった時、
    僕はこう書いてました。

    user = User.order("id ASC")
    user_min = user.first
    user_max = user.last

    rails2時代の感覚だと、1行目でレコードのデータが user に格納され、
    2行目と3行目では、ただの配列の操作を行ってデータを格納する処理ですが、
    実際には1行目では user にデータは格納されず、
    2行目と3行目でクエリが発行されてデータが格納されます。
    つまり、1回余分です。

    これじゃあ無駄なので、1行目を

    user = User.order("id ASC").all

    としました。

    こうすれば、1行目で user にデータが格納され、クエリ発行は1回です。

    時代はもうRails3.1

    まだ、Arelに馴染んでなかったといってしまえばそれまでですが、
    rails2の感覚でいると、いろいろ壁があるなーと実感しました。
    今やもう3.1ですし、次はcoffeescriptをやらないといけないかなと思ってます。
    上記は、あくまで自分の解ですが、他の解とか、そもそも論が何かあればツッコミのほどよろしくお願いします。

      はてなブックマーク - RubyKaigi2011に参加してきました
      このエントリーをはてなブックマークに追加

      山本です。
      海の日を含んだ3連休、みなさん、めいいっぱい楽しめたでしょうか。

      さて、私はというと、世のRubyistの祭典、「日本Ruby会議2011」に、河野と参加してきました。
      Rubyistとしての勉強のため、そして、ZENPREを使って、まつもとゆきひろさんのキーノートを配信するためです。

      初めてのRubyKaigi

      今年で最後となるRubyKaigiですが、参加は初めてです。
      ですので、どんな雰囲気なのか、どんな発表があるのか、全く想像がつきませんでした。
      いち地方都市から、不安を覚えながらのこのこと来てしまいました。

      発表の中身

      発表は「大ホール」と「小ホール」に別れ、
      前者はビックネームな方々の発表で、後者はコアデベロッパー向けの技術よりな話、という印象です。
      個人的には、よく使わせていただいている「jpmobile」の話を興味深く聞かせていただきました。

      闇RubyKaigi

      怪しげなタイトルですが、きっと参加者によっては、これがメインだと捉えている人もいるのでしょう。
      本編に登壇できなかった方達の、もしくは本編では発表できないような方達のためのLT大会がありました。
      この闇RubyKaigiでLT枠がもらえるかもしれない、とのことで、
      ZENPREを紹介すべく、お気楽に応募してみました。

      それが誤算でしてね。

      皆さんの発表の面白いこと。
      最初の基調講演を見て、あまりの自分の普通のスライドに焦りを覚えてしましました。
      私の順番は4番目だったのですが、前のお三方は全くすべらない。
      これはまずいと思いつつ、開き直ってやった結果、結構ウケてもらえました。
      ZENPREに興味を持たれた方もいたので、一安心でした。

      Matzのキーノート配信

      RubyKaigi最終日、最後のRubykaigiの最後の基調講演を務めるのは、まつもとゆきひろさんです。
      ZENPREでは、この模様を配信しました。
      タイトルは「三題噺: 振子とPGと百年の言語」と題して、
      振り子を例に挙げて、今後のプログラム業界がどういう道を進んでいくのかという話を中心に講演されました。
      私は、何回はまつもとさんの講演を見ているのですが、
      かなりリラックスして、活き活きとしている講演は初めてだったかなと思います。
      それだけ、この場このイベントを愛してらっしゃるということでしょうか。

      グランドフィナーレ


      最後はスタッフの方が全員壇上に上がり、グランドフィナーレです。
      これだけ大きいイベントを支えているのですから、責任もそれぞれ大きいことでしょう。
      スタンディングオベーションで拍手喝采です。

      謝辞

      ZENPREの配信にあたり、ご協力ご尽力いただきました皆様に、感謝いたします。
      本当にありがとうございました。

      まつもとさんの講演をいつでも

      まつもとさんの講演の模様は、ZENPREにて公開中です。
      見逃した方は、ぜひ一度以下のページからご覧ください。

      zenpre.net/p/rb11mz

        はてなブックマーク - rails と jquery treeview でディレクトリツリーをらくらく実装する
        このエントリーをはてなブックマークに追加

        ども、Fusic 河野です。
        だいぶ久しぶりですね。

        今度の rubykaigi2011 に参加させて頂くこととなりました!
        会場で見かけたら、ぜひお気軽にお声をかけてくださいませ。

        [rubykaigi2011]
        rubykaigi.org/2011/

        それと、もう一つ告知です。
        来る7月28日(木)、福岡で活動している Androidの会福岡支部九州GTUG
        HTML5+α福岡iDevQ、そして、AppleKnight の4つのコミュニティが
        福岡県Ruby・コンテンツ産業振興センターに集結し、同時に勉強会、懇親会を行います。

        ご興味のある方は、ぜひともご参加ください!!
        参加登録は下記のリンク先より facebook にて参加表明をお願いいたします。

        [futuresync]
        futuresync.jp/

        さて、わたくし、前回の記事でも書きましたが、主に ruby on rails を
        やっており、ZENPRE の iPhone アプリを担当させていただいてます。

        今回とあるお客様の rails 案件にて、ツリービューを作る必要がありました。
        一から作ろうかと思っていたところ、jquery ui の treeview を見つけ、
        使ってみたので、簡単なサンプルとともにご紹介をします。

        いやー、それにしてもコレ凄く便利です!!

        まずは、バージョン確認です。

        $ ruby -v
        ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux]
         
        $ rails -v
        Rails 3.0.9

        rails のプロジェクトを作成します。

        $ rails new treeview_test
        $ cd treeview_test/
        $ rm public/index.html

        prototype.js を削除ります。
        サヨナラ〜、お元気で〜♪

        $ vim Gemfile
         
        gem 'jquery-rails'
         
        $ rails g jquery:install

        ツリービューを表示するためのコントローラを作成します。

        $ rails g controller Treeviews index
        $ vim routes.rb
         
          root :to => "treeviews#index"

        そして、本日の主役のご登場!
        jquery treeview を下記よりダウンロードします。
        bassistance.de/jquery-plugins/jquery-plugin-treeview/

        js や css、jpg などを rails の各ディレクトリにコピーします。
        画像は、images に “treeview” というディレクトリを
        作成し、そこにコピーしています。
        そして、jquery.treeview.css に記載されている画像のパスを
        ちょっと変更します。

         images/xxxx → ../images/treeview/

        treeview を取り込みます。

        $ vim app/views/layouts/application.html.erb
         
        <!DOCTYPE html>
        <html>
        <head>
          <title>TreeviewTest</title>
          <%= stylesheet_link_tag :all %>
          <%= javascript_include_tag :defaults %>
          <%= javascript_include_tag 'jquery.treeview' %>
          <%= javascript_include_tag 'jquery.treeview.edit' %>
          <%= javascript_include_tag 'jquery.treeview.async' %>
          <%= csrf_meta_tag %>
        </head>
        <body>
         
        <%= yield %>
         
        </body>
        </html>

        ツリービューを表示するため view を書き換えます。

        $ vim app/views/treeviews/index.html.erb
         
        <script type="text/javascript">
        $(document).ready(function(){
          $("#example").treeview({});
        });
        </script>
         
        <ul id="example" class="filetree">
        	<li><span class="folder">Folder 1</span>
        		<ul>
        			<li><span class="file">Item 1.1</span></li>
        		</ul>
        	</li>
        	<li><span class="folder">Folder 2</span>
        		<ul>
        			<li><span class="folder">Subfolder 2.1</span>
        				<ul>
        					<li><span class="file">File 2.1.1</span></li>
        					<li><span class="file">File 2.1.2</span></li>
        				</ul>
        			</li>
        			<li><span class="file">File 2.2</span></li>
        		</ul>
        	</li>
        	<li class="closed"><span class="folder">Folder 3 (closed at start)</span>
        		<ul>
        			<li><span class="file">File 3.1</span></li>
        		</ul>
        	</li>
        	<li><span class="file">File 4</span></li>
        </ul>

        完成です!!
        いやー、ほんとめちゃくちゃ簡単ですね!!
        まー、これだけだと寂しいのとせっかくの rails も意味がないので
        rails にディレクトリ一覧を返す関数を作成し、ajax 使って
        ディレクトリ階層を動的に表示できるように変更します。
        おー!rails っぽいですね!

        routes にパスを追加します。

        $ vim config/routes</code>
         
          match '/treeviews/get_dir_list' => 'treeviews#get_dir_list'

        さっきの view を書き換えます。

        $ vim app/views/treeviews/index.html.erb
         
        <script type="text/javascript">
        $(document).ready(function(){
          $("#example").treeview({});
          $("#example2").treeview({
        		url: "<%= treeviews_get_dir_list_path %>"
          });
        });
        </script>
         
        <h4>通常のツリービュー表示</h4>
         
        <ul id="example" class="filetree">
        	<li><span class="folder">Folder 1</span>
        		<ul>
        			<li><span class="file">Item 1.1</span></li>
        		</ul>
        	</li>
        	<li><span class="folder">Folder 2</span>
        		<ul>
        			<li><span class="folder">Subfolder 2.1</span>
        				<ul>
        					<li><span class="file">File 2.1.1</span></li>
        					<li><span class="file">File 2.1.2</span></li>
        				</ul>
        			</li>
        			<li><span class="file">File 2.2</span></li>
        		</ul>
        	</li>
        	<li class="closed"><span class="folder">Folder 3 (closed at start)</span>
        		<ul>
        			<li><span class="file">File 3.1</span></li>
        		</ul>
        	</li>
        	<li><span class="file">File 4</span></li>
        </ul>
         
         
        <h4>sync させたツリービュー表示</h4>
        <ul id="example2" class="filetree"></ul>

        treeview の url に先ほど routes に追加したパスを記載します。

        controller もゴニョゴニョと追加します。

        $ vim app/controllers/treeviews_controller.rb
        class TreeviewsController < ApplicationController
         
          def index
          end
         
          def get_dir_list
            root_flg = (params["root"] == "source") ? true : false
            path = "./"
            path = params["root"] unless root_flg
            arry = []
            d = dir_list(path, arry)
            render :json => arry || [], :layout => false
          end
         
        protected
          def dir_list(path, arry=[], root_flg=false)
            Dir.glob("#{path}/*").map do |d|
              classes = "file"
              classes = "folder" if FileTest.directory?(d)
              hasChildren = (FileTest.directory?(d)) ? true : false
            	h = {"id" => d, "text" => File.basename(d), "path" => File.dirname(d), "expanded" => false, "classes" => classes, "hasChildren" => hasChildren, "children" => []}
              arry << h
            end
            arry
          end
         
        end

        dir_list() の関数でディレクトリ情報の hash を作成し、view 側に json で返します。
        返された json を treeview 側が解析してツリービューを表示します。
        返す hash の id のところがミソでして、ここにパスを記載していると
        treeview にてディレクトリを選択された場合、params["root"] に選択された
        ところのパスが渡されます。
        一番上のルートの場合には、params["root"] には、”source” という文字が渡ってきます。

        今回もいつもの如くソースは github にあげてます。
        また、サンプルをここに置いてますので実際の動作を確認できます。
        今回始めて dotcloud を使ってみました。
        これまためちゃくちゃ便利ですねー!
        dotcloud で rails を動かす方法とかは、また次回にでも、デモ。

        それでは、良い rails ライフを〜。

        [ソース]
        github.com/sora0513/TreeViewTest

        [デモ]
        8befe980.dotcloud.com/