MerbでDataMapperを使っている場合にアソシエイションを記述する場合、 以下のようにhasメソッドを利用します。

   1  class User
   2    include DataMapper::Resource
   3    
   4    property :id,     Serial
   5    property :login,  String
   6  
   7    has n, :assignments
   8    has n, :groups, :through => :assignments
   9  end

第一引数はカーディナリティを指定します。nは DataMapper::Associations#nで、値はInfinityです。 1, 2, 3などの数値や、1..3, 5..n などのRangeを指定する事もできます。

上の例のように、Railsのhas_many :throughのようなこともできます。

posted by Png genki on Fri 21 Nov 2008 at 16:55

Merbではlink_toなどのヘルパーでURLを指定する時に、 urlメソッドを利用しますが、 そこで利用するNamedRouteを定義するためには、 config/router.rbの中で以下のように記述します。

   1    match('/foo').to(:controller => 'foo').name(:foo)

これをViewの中から参照する場合は、

   1  <%= link_to 'Foo', url(:foo) %>

の様になります。

posted by Png genki on Fri 21 Nov 2008 at 12:18

C言語では、 #ifdef #ifndef を使うことによって、条件付きのコンパイルが可能となる。

#ifdefの使い方と意味

#ifdefは、次のようにして使う。

   1  #ifdef MACRO
   2   ・
   3   ・
   4   ・
   5  #endif

これは、「MACROが定義されている場合は、#ifdef~#endifの中を有効にする」という意味である。

#ifndefの使い方と意味

次に、#ifndefは、逆の意味で、以下のように使う。

   1  #ifndef MACRO
   2   ・
   3   ・
   4   ・
   5  #endif

これは、「MACROが定義されていない場合は、#ifndef~#endifの中を有効にする」という意味である。

C言語でヘッダーを書くときの定石

この#ifndefを使ってヘッダーを書く、C言語の定石(?)がある。

以下のような、ヘッダーファイル my.h を定義する。

   1  #ifndef MY_H    /* ヘッダーの最初 */
   2  #define MY_H
   3   ・
   4   ・
   5   ・
   6  #endif          /* ヘッダーの最後  */

こうすることによって、複数のソースから my.h がインクルードされていたとしても、 確実に1度だけ my.h の中身を有効にすることができる。

これで、ヘッダーファイルの管理も楽になりますね!!

posted by Png y_tsuda on Fri 21 Nov 2008 at 10:14

MerbでORMとしてDataMapperを使っている場合は、 コントローラのアクションが、以下のように仮引数でパラメータを受け取るようなデザインになっています。

   1    def show(id)
   2      @user = User.get(id)
   3      raise NotFound unless @user
   4      display @user
   5    end

このとき、Merbは、merb-action-argsというモジュールを使い、 仮引数idの名前をしらべ、Railsでいうところのparams[:id]の情報をもってきます。

merb-action-args は、以下のようにUnboundMethodの仮引数を取得します。

   1  def foo(id, bar); end
   2  method(:foo).get_args
   3  #=> [[[:id], [:bar]], []]

内部的には ruby2ruby を使っている模様。これはすごい。

See Also

posted by Png genki on Thu 20 Nov 2008 at 17:35

merb-genのサブコマンドには、resource, model, resource_controller, controllerという感じで、リソース版とそうではない版があるようなのですが、 違いが何なのかを調べてみました。

まずはmodel

   1  % merb-gen model foo
   2       (snip)
   3       [ADDED]  spec/models/foo_spec.rb
   4       [ADDED]  app/models/foo.rb

次はresource

   1  % merb-gen resource foo
   2       (snip)
   3       [ADDED]  spec/models/foo_spec.rb
   4       [ADDED]  app/models/foo.rb
   5       [ADDED]  spec/requests/foos_spec.rb
   6       [ADDED]  app/controllers/foos.rb
   7       [ADDED]  app/views/foos/index.html.erb
   8       [ADDED]  app/views/foos/show.html.erb
   9       [ADDED]  app/views/foos/edit.html.erb
  10       [ADDED]  app/views/foos/new.html.erb
  11       [ADDED]  app/helpers/foos_helper.rb

なるほど。resourceの方はRailsのscript/generate resourceのように、 コントローラやViewも作成してくれるようです。

ではcontrollerとresource_controllerの違いはなんでしょうか。 まずはcontroller

   1  % merb-gen controller foo
   2       (snip)
   3       [ADDED]  app/controllers/foo.rb
   4       [ADDED]  app/views/foo/index.html.erb
   5       [ADDED]  spec/requests/foo_spec.rb
   6       [ADDED]  app/helpers/foo_helper.rb

続いてresource_controller

   1  % merb-gen resource_controller foo
   2       (snip)
   3       [ADDED]  spec/requests/foo_spec.rb
   4       [ADDED]  app/controllers/foo.rb
   5       [ADDED]  app/views/foo/index.html.erb
   6       [ADDED]  app/views/foo/show.html.erb
   7       [ADDED]  app/views/foo/edit.html.erb
   8       [ADDED]  app/views/foo/new.html.erb
   9       [ADDED]  app/helpers/foo_helper.rb

なるほど、resourceからmodelを差し引いた感じのものが生成されるようです。 最初から入っているuserモデルのコントローラを生成するのに便利そうですね。

posted by Png genki on Thu 20 Nov 2008 at 13:06

PassengerはRackに対応しているので、Merbも動かすごとができます。

以下のように、Merbアプリケーションのディレクトリの直下に config.ruファイルを作成して置くだけです。

   1  require 'rubygems'
   2  require 'merb-core'
   3  Merb::Config.setup(:merb_root   => ".",
   4    :environment => ENV['RACK_ENV'])
   5  Merb.environment = Merb::Config[:environment]
   6  Merb.root = Merb::Config[:merb_root]
   7  Merb::BootLoader.run
   8  
   9  # Uncomment if your app is mounted at a suburi  
  10  #if prefix = ::Merb::Config[:path_prefix] 
  11  #  use Merb::Rack::PathPrefix, prefix 
  12  #end 
  13  
  14  run Merb::Rack::Application.new

ちなみに ru はRack Upの事だと思われます。

ハマった点として、 Merbアプリのひな形の"/"で表示される画面は、エラーページなので、 production環境のPassengerで動かすとエラーとして扱われてしまいます。 なので、動作確認する場合、 なにかしらコントローラを作ってから試す必要があります。

posted by Png genki on Thu 20 Nov 2008 at 12:14

いつのまにか今まで動いていたRailsアプリケーションが、以下のようなエラーを出すようになっていました。

This version of RMagick was created to run with ImageMagick 6.4.3 but ImageMagick 6.4.5 is in use

どうやら、port upgradeを行ったときにlibmagickのバージョンがあがり、 インストールされているRMagickとのバージョンの対応が崩れてしまったようです。

一度RMagickの最新バージョンをアンインストールし、 もう一度gemコマンドでインストールし直した所、解決しました。

posted by Png genki on Thu 20 Nov 2008 at 02:20

シドニーに帰省するついでに、11月19日に地元のRuby on Railsイベントに参加してきた。参加したというか、LTでRubyKaigi 2009の宣伝してきた。オリジナルな発表ではなく、角谷さんRubyConf 2008のLTスライドを無断に手を加えて再利用した。すみません!ありがとう!

Why You Should Attend RubyKaigi 2009

Slideshare: Why You Should Attend RubyKaigi 2009

他のLTは日本にイベントに鈍れず、クオリティがけっこう高かった。

  • RailsCamp 4のイベントレポートとふりかえり
  • いくつかのライブラリの紹介とデモ:
    • iUi:RailsによるiPhone開発ライブラリ -Prawn: PDF生成ライブラリ
  • デモをいくつ
  • ネタトークをいくつ
    • paml: Passenger+haml
    • C64風プレゼンでView/Controllerのrefactoringを紹介
  • 最後のおまけトークはDr Nictabtabというbashでいろんなコマンドのtab補完拡張を自動生成するプロジェクトだった。

バーで開催したから、ビールを片手に発表した。あ、たのしかった。

posted by Face lchin on Thu 20 Nov 2008 at 01:34

windowsで開発していてコマンドプロンプトでutf8な出力結果が文字化けして困ることがある。railsのrakeとかrspecとかtestunitとか。

-コマンドプロンプトの左上のアイコンをクリックして、プロパティでフォントを日本語フォントにする -画面内でchcp 65001を実行(文字コードが切り替わる)

posted by Face ysakaki on Wed 19 Nov 2008 at 16:42

s21gブログではmasterの他にdeployブランチがあり、下記のようなフローで運用しています。

  1. 普段はmasterにpushして
  2. deployできる状態になったらdeployにmasterの変更を反映
  3. deployをpush&cap deploy

ローカルでもdeployブランチとすればよかったのですが、ローカルを意識したいのでlocal_deployという名前にしてみました。そのことで勉強になったので、書いてみたいと思います。

リモートのoriginブランチを確認

   1  git branch -a   
   2  * master
   3    origin/HEAD
   4    origin/deploy
   5    origin/master

ローカルにブランチを作成

   1  git branch local_deploy origin/deploy 
   2  git branch -a #追加されているのを確認
   3  git checkout local_deploy

また下記のコマンド1つで、ブランチを作ってcheckoutまでをやってくれます。

   1  git checkout -b local_deploy origin/deploy

git checkout -b <new> <start-point>
create a new branch <new> referencing <start-point>, and check it out.
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#manipulating-branches

masterの変更をlocal_deployブランチに反映

   1  git checkout master
   2  git pull --rebase -v #masterを最新に, +verbose
   3  git checkout local_deploy
   4  git merge master
   5  git push origin local_deploy:refs/heads/deploy

git merge masterの前後でちゃんとファイルが変更されているか見てみましたがちゃんとmergeできていました。また、pushの際のsrc:dstの指定の仕方がこのままでは面倒なので調べて後日また書いてみようと思います。

コンフリクトした時は修正後コミットし、上のpushコマンドを発行すればokです。

   1  #(コンフリクトしたファイルを修正後)
   2  git add some.file
   3  git commit -m "merged from master"

posted by Png satoko on Wed 19 Nov 2008 at 13:28 with 2 comments