「rubywaves概要」の編集履歴(バックアップ)一覧に戻る

rubywaves概要 - (2008/04/23 (水) 23:08:58) の編集履歴(バックアップ)


Waves 概要

みんながするように Hello World から始めましょう。 Waves では、 mapping.rb ファイルに1行コードを書くだけで実現できます。 [fixme]するべきことすべてをどんなに簡単に行っているか考えてください。WavesはMVCフレームワークだけれど、時にMVCは過剰だとわかっています。[fixme]

path '/' { 'Hello, World!' }


リクエストラムダ

Waves のすべてはリクエストラムダから始まります。各マッピングはルールとブロックから成ります。 リクエストがルールにマッチしたときに、ブロックが実行されます。 ブロックには何でもおくことが出来ます。ルールには正規表現か任意のハッシュ値の制限のいずれかを含みます。正規表現にマッチするとブロックにパラメータが渡されます。

Hello world, version 2:

# /dan => Hello, Dan!
path %r{^/(\w+)$} { |name| "Hello, #{name.capitalize}!" }


Resource = Model + View + Controller

リクエストラムダは「リソース」(モデル・ビュー・コントローラの3層)の操作をサポートします。コントローラとビューを使うブロックへのマッピングルールを容易に記述する3つの特別なメソッドがあります。

use メソッドは、単にリソースコンテキストを設定するだけです。(例えば MVC クラスをインスタンス化する) controller メソッドがコントローラのスコープで内で適切なコントローラをインスタンス化し、リクエストを初期化し、ブロック引数を評価します。 view メソッド は通常、コントローラブロックを評価した結果を引数とする場合を除いて同様に動作します。さらに、view メソッドは関連テンプレートから様々なインスタンス変数からアクセス可能な予約されたハッシュを持つかもしれません。

何かを表示する一般的な規則:

 path %r{^/#{resource}/#{name}/?$} do | model, name |
   use( resource ) | controller { find(name) } | 
     view { |object| show( resource => object ) }
 end


何かをREST-スタイルで更新する一般的な規則:

 path %r{^/#{resource}/#{name}/?$}, :method => :post do | model, name |
    use( resource ) | controller { update(name) } | 
      view { |object| show( resource => object ) }
  end
 end


フィルタ

/admin で始まるどんな URL でも login と password を要求する:

 before %r{^/admin/} do | model, name |
   redirect('/login') unless session[:user]
 end

You don’t have to worry whether you might have inadvertantly created a security hole by adding a method to a controller that you forgot to hide or make private. You lock your application down in the request mapping rules and forget it about it.

Mapping Mixins

You can encapsulate sets of common rules using mixins. For example, Waves provides a set of rules for mapping “pretty URLs” to a simple CRUD controller. You can just include it in your mapping file to pick up all the necessary mapping rules:

include Waves::Mapping::PrettyUrls::GetRules
include Waves::Mapping::PrettyUrls::RestRules


Just In Time Resources

Waves allows you to implicitly define resources (MVC triples). You define the idioms you want to use for a given type of resource and Waves will define the necessary classes for you on the fly, when / if they are needed. This speeds up development and reduces the amount of documentation and testing required. It also encourages reuse.

In this example, we haven’t defined an Entry class, but the table exists in the database, which means we can access it programmatically as if we had defined it:

~/blog $ waves_console
irb(main):001:0> M = Blog::Models
irb(main):002:0> M::Entry.all
=> []


First Class Views

In Waves, a View is a class that attempts to map a request to a template. That’s it. However, you can define your own view class if you want. You can even have different Resources use different defaults. It’s up to you.

You can also provide helpers for use in your templates. Helpers are magic the same way that Views and Controllers are; an “intelligent default” is provided that mixes in a variety of helpful methods, but you can add to these, or explicitly define a helper for a specific resource.

The default helpers include support for nested views, layouts, markdown formatting, customizable form controls, and more.

Layouts

Specify the layouts right there in the view.

layout :admin, :title => @entry.title do

 # markup for blog entry editor here

end If you want to reuse views across layouts, just re-factor, like you would with anything else you want to reuse, using the view method:

layout :admin, :title => @entry.title do

 view :blog_entry, :editor_fragment, :entry => @entry

end There is no special naming convention for nested views, like prefixing views with underscores. You can do that if you want, but you don’t have to. You can nest any view within another view and you can have multiple, nested layouts if you want.

This means you can have layouts specific to various types of page elements (forms, dialogs, menus, whatever), not just for an entire Web page. Did you just realize you wanted all your forms to use H3 tags instead of H2? No problem, just change your form layout and your done.

Custom Form Properties

Since Waves uses Markaby as its primary templating engine, there is no real need for form helpers just to create a text box or other form control. However, most real-world Web applications have a strong need to consistently render the label, control, help text, control groups, etc., as well as support more sophisticated composite controls, like date pickers. So Waves provides a property helper that uses templates that you can modify to render complete property blocks within a form. When you modify one of these templates, all your application forms will get the new control.

  1. use our custom date template to render a date picker

property :type => :date, :name => reservation.start_date,

 :value => @reservation.start_date, :class => :required


Sessions

You can store things in file-based session (database sessions coming soon), from pretty much anywhere you deal with a Resource (the request mappings, controller blocks, view templates, etc.):

session[:user] = @user.id if User.authenticate( email,password)?


Inheritable Configurations

You can define hierarchies of configurations for use in testing, development, and production scenarios because configurations are just Ruby classes and attributes are inherited. You can also incorporate your own attributes into the configuration just by declaring them using the attribute method or by defining a class method on a configuration.

module Blog

 module Configurations
   class Development < Default
     host '127.0.0.1'
     port 3000
     reloadable [ Blog ]
     log :level => :debug  
     application do
       use Rack::ShowExceptions
       use Rack::Static, :urls => [ '/css', '/javascript' ], :root => 'public'
       run Waves::Dispatchers::Default.new
     end       
   end
 end

end

Configurable Applications

You can customize the request processing chain using the application configuration parameter. Thus, you can define your development configuration to use the ShowErrors Rack “middleware” and set your production configuration to include an analytics module. You can even replace or extend the Waves dispatcher with your own!

Soon, we’ll add the ability to customize which Rack::Handler to use, like this:

server :mongrel

True Code Reloading

During development, no one wants to have to keep restarting the server for each change you make to your code. So most frameworks will reload your code on each request. However, this often leads to hard to debug errors when previously defined constants remain in memory. Waves is the first framework that completely unloads old class or module definitions before reloading. Further, reloading is done only on demand, so you incur a minimum performance penalty.

Hot Patching

In production, this means you can “hot patch” your code, since code reloading is safe and since you can reload all of an application module’s code just by calling reload on it. In combination with LiveConsole, you can upload patches to your production servers and then reload the code on the fly without actually restarting your servers.

Cluster Support

Starting up server clusters is a breeze. Just set the ports attribute of your configuration to contain an array of the ports you want to listen on, and then run:

 rake cluster:start
 To restart, just do:
 rake cluster:restart


Thread Safety

I know it isn’t cool right now to do threads. But Ruby 1.9 will support native threading and the coarse-grained nature of most Web apps makes threads ideally suited for them. Threads share memory, meaning you can have more memory for actually processing requests. And even if you decide to use an event-driven model, isn’t it nice to know that using a thread-per-request model is an option? That’s why Waves is written to be thread-safe, using thread-safe libraries like Rack.

Migrations Support

Sequel provides support for migrations and Waves defines the basic Rake tasks necessary to use it. Migrations remains the most reliable way to safely version a database across multiple hosts, and that’s why Waves helps make it easy to use them.

It’s All Just Ruby

Everything is Waves is just Ruby code. And the libraries that Waves favors use the same approach. The configuration files are Ruby. The request mapping rules are just Ruby. Markaby is just Ruby. Sequel supports writing SQL queries as … you guessed it … Ruby. Rack applications are defined using just Ruby.

Furthermore, none of these libraries, including Waves, are intrusive by nature. They add a smattering of extensions to the core Ruby library (mostly via the extensions gem), but they only extend, they don’t override (well, except for RubyGems). So you can use Ruby however you want without unexpected surprises.

Ruby is such a great language, why should your framework get in its way? That is the underlying approach taken by Waves and its component libraries.

記事メニュー
人気記事ランキング
目安箱バナー