火曜日 1 27, 2009

(j)Ruby on Merb : create views

前回の続きです。

Viewを作成します。Railsの場合は、Scaffoldで一覧のviewを作ってくれますが、Merbは(まだ)そこまで自動生成されません。そこでまずindexページのviewから作成します。次のようになります。


<h1>Articles</h1>  
<table class="articlelist">
<tr>
<th>タイトル</th>
<th>記事</th>
<th>作成日時</th>
<th>更新日時</th>
<th colspan="3">Action</th>
</tr>
<% @articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td ><%= article.body %></td>
<td ><%= article.created_at %></td>
<td ><%= article.updated_at %></td>
<td ><%= link_to 'Show', resource(article)
%></td>
<td ><%= link_to 'Edit', resource(article,
:edit) %></td>
<td><%= delete_button article, 'Delete', :class =>
'delete' %></td>
</tr>
<% end %>
</table>
<%= link_to 'New', resource(:articles, :new) %>


一覧表示と編集/削除のリンク、そして新規記事作成へのリンクとなっています。新規記事の作成をクリックすると、まだnew.html.erbがデフォルトのままですので、作成画面が表示されません。そこで、続いて作成画面を作ります。


MerbもRailsと同様に、partialを使うことができます。そこでまずフォーム部分を作成します。_form.html.erbというファイルを/app/view/articles/の中に作り、以下のように作成します。



<%= error_messages_for @articles %> 
<p>タイトル: <%= text_field :title, :size =>"40" %></p>
<p>記事: <%= text_area :body,
:cols => "50", :rows => "5", :wrap => "SOFT" %></p>


続いて、new.html.erbに



<h1>新規記事作成</h1> 
<%= form_for(@article, :action => url(:articles) ) do %>
<%= partial :form %>
<%= submit "新規作成" %>
<% end =%>
<%= link_to '一覧に戻る', url(:articles) %>


とします。partialの扱いがRailsに比べて、シンプルになっています。参考:Merbのpartial


同様に、edit.html.erb、show.html.erbを編集します。


edit.html.erb



<h1>記事を編集</h1> 
<%= form_for(@article, :action => resource(@article)) do %>
<%= partial :form %>
<p> <%= submit "更新" %> </p>
<% end =%>
<%= link_to '一覧に戻る', url(:articles) %>


 


show.html.erb



<h1><%= @article.title %></h1> 
<p><%= @article.body %></p>
<%= link_to '編集', resource(@article, :edit) %> |
<%= link_to '一覧に戻る', resource(:articles) %> |
<%= link_to '削除', resource(@article, :delete), :class => 'delete' %>


ここで注意すべきなのが、delete。deleteアクションがデフォルトではarticle controllerにないので、このまま実行するとResource route not foundとなりエラーになります。(:class => 'delete'は後ほど説明します。)

そこで、destoryアクションを呼ぶdeleteアクションをarticle controller内に作成します。



 def delete(id)
@article = Article.get(id)
raise NotFound unless @article
if @article.destroy
redirect resource(:articles)
else
raise InternalServerError
end
end


これで削除することができるようになりましたが、このままでは削除する際に何の確認もなく、いきなり削除されてしまうため、Javascriptで確認ダイアログを表示させます。

MerbはデフォルトでjQueryがバンドルされていますので、それを利用します。jQueryを利用し、カスタマイズしたjavascriptを使いたい場合は、/public/javascripts/application.jsを編集します。そこでapplication.jsを以下のように、編集します。



$(document).ready(function() { 
$('.delete').click(function() {
var answer = confirm('削除してもよろしいですか?');
return answer;
}); });


これは、deleteというclassがクリックされた場合、”削除してもよろしいですか?”というダイアログを出すというものです。


そして、/app/view/layout/application.html.erbにjQueryとこのapplication.jsを読み込むように設定します。



<script src="/javascripts/jquery.js" type="text/javascript"></script> 
<script src="/javascripts/application.js"
type="text/javascript"></script>


これで、viewは完成です。

金曜日 1 23, 2009

(j)Ruby on Merb : migration & merb console

前回の続きです。今回はmigrationとmerb console。

最初に前回の補足です。titleとbodyが空欄であることを避けるために、前回はmodelで



validates_present :title
validates_present :body


というように、検証しましたが、同様にmodelの



property :title, String


に、



property :title, String, :nullable => false


と追記することでも同じ検証が行えます。またさらにオプションを追記することで、範囲の設定やエラーメッセージのカスタマイズ等を行うこともできます。



property :name, String,:nullable => false,  :within => 3...40 
property :price, Float, :nullable => false, :scale => 2, :precision => 5,
:message => "価格は$0.01から、$999.99までで入力してください"


では、最初にmodelを元に、マイグレーションを行います。
Merb1.0.8.1を使っている場合は、注意が必要です。

dependecies.rbに含まれる、デフォルトで生成されるcacheストアのコードにバグがあり、そのままでは以下のように、migrationに失敗します。



  %  rake db:automigrate
(in /Sources/Merb/cache)
Loading init file from /Sources/Merb/cache/config/init.rb
Loading /Sources/Merb/cache/config/environments/development.rb
Loading init file from /Sources/Merb/cache/config/init.rb
Loading /Sources/Merb/cache/config/environments/rake.rb
rake aborted!
default store already setup
/Sources/Merb/cache/rakefile:24
(See full trace by running task with --trace)


そこで、dependecies.rbの9行目からのMerb:Cache.setupを以下のようにエディットします。



 Merb::Cache.setup do
unless defined? CACHE_SETUP
register(:default, Merb::Cache::FileStore, :dir =>
Merb.root / :tmp / :cache)
end
CACHE_SETUP = true
end
end


これで、マイグレーションが動作しますので、実行します。



rake db:automigrate


automigrateはmodel及びmigrationファイルを元に、データベースを初期化して、テーブルを作成します。


マイグレーションが完了したら、一度merbを起動してみます。アプリケーションルートで



merb


と入力すると、開発用サーバが起動するので、http://localhost:4000/articles にアクセスしてみてください。デフォルトのview


が表示されていればここまでは問題なく進んでいます。viewはRailsと同様に、/app/views/articles/xxx.html.erbがテンプレートとして呼び出されます。またアプリケーション全体のテンプレートは/app/views/layout/application.hmtl.erbと、これもRailsと同様です。


ここで、Railsのscript/consoleにあたるmerb -iを使ってみたいと思います。このmerb -iを使うにはmongrelが必須となりますので、インストールされていない場合は、インストールしておいてください。

まず起動します。アプリケーションルートで



   merb -i


そうすると、



Loading init file from /Sources/Merb/blog/config/init.rb
Loading /Sources/Merb/blog/config/environments/development.rb
~ Connecting to database...
~ Loaded slice 'MerbAuthSlicePassword' ...
~ Parent pid: 1547
~ Compiling routes...
~ Activating slice 'MerbAuthSlicePassword' ...
irb: warn: can't alias context from irb_context.
>>


というようなダイアログが表示されます。そこでレコードを加えて見たいと思います。



>> Article.count
~ (0.000115) SELECT COUNT(\*) FROM "articles"
=> 0
>> Article.create(:title => 'test',:body => 'this is a test post.')
~ (0.002843) INSERT INTO "articles" ("updated_at", "body", "title", "created_at") VALUES ('2009-01-23T15:07:40+09:00', 'this is a test post.', 'test', '2009-01-23T15:07:40+09:00')
=> #
body="this is a test post." title="test" created_at=#>
>> Article.count
~ (0.000075) SELECT COUNT(\*) FROM "articles"
=> 1


このように、Rails consoleと全く同じように使う事ができます。Merb Consoleの特徴的な機能として、サンドボックス機能があります。

この機能は、現在開発中のため、まだ正常に動作しませんが、サンドボックス内で行った作業がサンドボックスを終了するとロールバックされるというものです。
便利なので、早期の実装が待たれるところです。


現状ではどのように、動作するかみてみます。



>> Article.count
~ (0.000094) SELECT COUNT(\*) FROM "articles"
=> 1
>> merb.open_sandbox!
Loading development environment in sandbox (Merb 1.0.8.1)
Any modifications you make will be rolled back on exit
=> [Merb::Orms::DataMapper]
>> Article.all.destroy!
~ (0.002382) DELETE FROM "articles"
=> false
>> Article.count
~ (0.000076) SELECT COUNT(\*) FROM "articles"
=> 0
>> merb.close_sandbox!
Modifications have been rolled back
=> nil
>> Article.count
~ (0.000088) SELECT COUNT(\*) FROM "articles"
=> 0
>>


このように残念ながらロールバックはされません。


ということで、今回はここまで

merb 1.0.8.1 release

merb1.0.8.1がリリースされました。

変わったのは、dependencies.rbで、data_objectのバージョン等もデフォルトで記載されるようになっています。


# dependencies are generated using a strict version, don't forget to edit the dependency versions when upgrading.
merb_gems_version = "1.0.8.1"
dm_gems_version = "0.9.9"
do_gems_version = "0.9.10.1"

# For more information about each component, please read http://wiki.merbivore.com/faqs/merb_components
dependency "merb-core", merb_gems_version
dependency "merb-action-args", merb_gems_version
dependency "merb-assets", merb_gems_version
dependency("merb-cache", merb_gems_version) do
Merb::Cache.setup do
register(Merb::Cache::FileStore)
end
end
dependency "merb-helpers", merb_gems_version
dependency "merb-mailer", merb_gems_version
dependency "merb-slices", merb_gems_version
dependency "merb-auth-core", merb_gems_version
dependency "merb-auth-more", merb_gems_version
dependency "merb-auth-slice-password", merb_gems_version
dependency "merb-param-protection", merb_gems_version
dependency "merb-exceptions", merb_gems_version

dependency "data_objects", do_gems_version
dependency "do_sqlite3", do_gems_version # If using another database, replace this
dependency "dm-core", dm_gems_version
dependency "dm-aggregates", dm_gems_version
dependency "dm-migrations", dm_gems_version
dependency "dm-timestamps", dm_gems_version
dependency "dm-types", dm_gems_version
dependency "dm-validations", dm_gems_version
dependency "dm-serializer", dm_gems_version

dependency "merb_datamapper", merb_gems_version




金曜日 1 16, 2009

(j)ruby on Merb : create resource and validator

前回の記事に追記したように、DataObjectsがJRubyで現在のところ、満足に動作しませんが、もうすぐサポートしたものが正式にリリースされるようなので、JRubyではなく、MRIをつかってMerb+Datamapperで遊んでいきたいと思います。

ちなみにソース(そんな大げさなものではないですが)は、githubで公開しています。

まず前回作ったアプリのディレクトリに移動し、config/dependencies.rbのdatamapperのバージョンを書き換えます。

dependencies.rbの


dm_gems_version	=	"0.9.8"




dm_gems_version	=	"0.9.9"



に変更します。Merbアプリケーションが起動する際に、最初にロードされる設定ファイル(正確にはinit.rbがロードされますが、init.rbの冒頭でdependencies.rbが呼ばれているため)で、アプリケーションが依存するMerb関連のgemをバージョンとともに定義したものです。

ここに定義されているgemは、機能としてはいわゆるgemというより、Merbのプラグイン的なものととらえる方が良いのかもしれません。

dependencies.rbがロードしおわると、init.rbの続きがロードされます。このinit.rbには、


use_orm :datamapper
use_test :rspec
use_template_engine :erb



というように、このMerbアプリケーションで使用する、ORM、テストフレームワーク、テンプレートエンジンが記載されており、これを変更することでもそれぞれのコンポーネントを変更することができます。もちろん変更した場合は、dependencyの宣言も変わってきます。

例えば、datamapperのかわりに、activerecordを使う場合は、


use_orm :activerecord



となり、dependency部分は、dm-xxxの部分はすべて削除し、merb_datamapperのかわりに、


dependency "merb_activerecord"



という感じになります。

では、続きです。RailsのScaffoldに相当するのが、Resourceです。resourceを生成することにより、model, controller, デフォルトのviewが自動生成されます。Stringのtitleと、TextのBoby,Datetimeのcreated_at,updated_atを作成します


merb-gen resource article title:string,body:text,create_at:datetime,updated_at:datetime



実行すると、model,controller,view以外にconfig/router.rbに


resources :articles



というルーティングが追加されます。

ここで、生成された article modelファイルを確認します。


class Article
include DataMapper::Resource

property :id, Serial

property :create_at, DateTime
property :updated_at, DateTime
property :body, Text
property :title, String

end




このように、Railsというかactiverecordでは、スキーマの定義をmigrationファイルで行いましたが、datamapperではmodelファイルに直接記述します。
ちなみにMerb+activerecordの場合は、schema/migration/番号_resourcename_migration.rbというマイグレーションファイルが生成され、これを元にRailsと同様にmigrateすることになります。

つぎにtitleとbodyが空欄であることをさけるため、validateしたいと思います。datamapperでのvalidateは、modelに


validates_present :title
validates_present :body



というように書きます。もちろんvalidates_present以外にもさまざまなvalidatorが用意されています。


#入力されていないことの検証
validates_absent :spam

# zip_codeが7桁であることの検証
validates_length :zip_code, :is => 7

# ageが3桁以内であることの検証
validates_length :age, :in => 1..3

# passwordとpassword_confirmationが同一であることの検証
validates_is_confirmed :password

# passwordとpassword_repeatが同一であることの検証
validates_is_confirmed :password, :confirm => :password_repeat

# registrationが正規表現にマッチしていることの検証
validates_format :registration, :with => /[A-Z]{3}-[0-9]{3}/

# emailがメールアドレスであることの検証
validates_format :email, :as => :email_address

# homepageがurlであることの検証
validates_format :homepage, :as => :url

# ageがintegerであることの検証
validates_is_number :age, :integer_only => true

# percentageが数字であることの検証
validates_is_number :percentage

# emailが一意であることの検証
validates_is_unique :email




さらに独自にvalidatorを定義することももちろん可能で、たとえばpriceが正の値であることを検証したい場合は、


validates_with_method :price, :positive_price?
def positive_price?
if @price <= 0.0
[false, "価格には正の値を入力してください"]
else
true
end
end



というようにカスタムメソッドを設定してやると、独自のvalidatorをつくることができます。

長くなってきたので、ほとんどコーディングしてませんが、今回はここで終了です。

最後に、今回の作業をMerb+activerecordで行ったものも参考になるか分かりませんが、githubに置いておきました。

金曜日 1 09, 2009

jruby on Merb : datamapper & merb-gen

前回の記事で、DatamapperのDBドライバがJRuby未対応と書きましたが、ようやく対応バージョンがリリースされたようです。

Merb + ActiveRecordで遊んで見るつもりでしたが、ORMをARにするといろいろと設定し直さないといけないところが出てくるので、せっかくリリースされたこともあり、Merb + Datamapperであそんでみたいと思います。

[1/15追記]申し訳ございません。現状インストールはできますが、実装が不十分なようで、(特にdatamapperとの連携部分)merb+datamapperでは動作しないことが判明しました。したがってJRubyで使うことはまだできません。大変申し訳ございません。

ただ、JRuby用Datamapperのドライバは現状開発中でgemのレポジトリにははいっていません。そのため、githubからダウンロードしてインストールする必要があります。

まずgit clone


$ git clone git://github.com/sam/do.git



できたディレクトリに移動して、ビルド&インストール。


$ cd do
$ jruby -S rake install



これでderby, sqlite3, postgres, mysql, hsqldb, そしてjdbc接続のドライバがインストールされます。

gem listすると、0.9.11のdo_xxxというgemがインストールされているはずです。

ということで、Merb+Datamapperを触っていきます。ブログアプリを作っていきたいと思います。

勉強しながら書いているので、間違いもあるかと思います。お気付きの場合、指摘していただけると幸いです。

Railsのrailsコマンドにあたるのが、merb-genです。これを使ってアプリケーションを生成します。


$ jruby -S merb-gen app blog



ところで、merb-genだけを入力するとオプションが表示されます。そのオプションの中に、アプリケーションのひな形を生成するオプション、app,coreとflat,very_flatがあると思います。それぞれで生成されるMerbアプリケーションの構成が異なります。


  • app : 最も標準的なひな形。jQueryやdependencies.rbなど全部入り。

  • core : railsのようなひな形。jQueryやdependencies.rb, database.ymlなど含まず

  • flat : view,controller1つずつ、framework.rb(設定)の極小ひな形。

  • very_flat : ファイル1つ(veryflat.rb)ですべての設定を行う超極小ひな形。



という構成になるようです。appでは、ORMやテストフレームワーク、テンプレートエンジンはデフォルト(それぞれ、Datamapper, RSpec, erb)を使用する設定でひな形が生成されます。これらをデフォルトから変更したい場合は、coreを使います。例えば、ORMをActiverecord,テンプレートエンジンをhamlにしたい場合は、


$ jruby -S merb-gen core test --orm=activerecord --template-engine=haml



というようになります。続きは次回。

水曜日 1 07, 2009

jruby on merb : install

遅くなりましたが、明けましておめでとうございます。本年もよろしくお願いします。

今年はjruby-users.jpのコンテンツをちゃんとつくります


Rails3でマージされることになったMerb。

面白そうなので、触ってみようと思います。もちろんJRubyで。今回はとりあえずインストール

MerbはデフォルトではORMにDataMapperを使用しますが、DataMapper(以下DM)のDBドライバがまだJRubyに対応していないため,ORMにはActiveRecordを使用することにします。またこの関係で、通常の


jruby -S gem install merb



ではdo_sqlite3(DMのsqlite3用ドライバ)のインストールにこけてしまうので、インストールにも一工夫必要です。
ではインストール

開発サーバとしてglassfish、dbとしてsqlite3を使うので、インストールしていない場合はインストール。また(jdbc-)activerecordもインストールしていない場合はインストールします。


jruby -S gem install glassfish activerecord  activerecord-jdbcsqlite3-adapter 



インストール後、merbをインストール。


jruby -S gem install merb-core merb-more merb_activerecord



これでDM以外のMerbに必要なモジュールとMerbからactiverecordを使うモジュールがインストールされます。

ということで実際のアプリケーション作成は次回!

About

Tomo

Search

Archives
« 4月 2014
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
今日