Rails*Javascript 要するにRJS
JavascriptやっほいAjaxやっほい な最近だけど
「この画面かっけー」とか思いつつもなかなか手をつけられない僕みたいな人はきっと僕だけじゃないはず
というわけで今回はRJSについて記事を書くよ!
3日前まで「RJSとかイラネ」とか言っててすいませんすいません。
なにはともあれサンプル。
今回はViewだけで完結するサンプルです。
<p id="test"> testtest </p> <%= link_to_function("表示する。"){|page| page['test'].show}%> <%= link_to_function("非表示にする。"){|page| page['test'].hide}%> <%= link_to_function("highlight"){|page| page.visual_effect(:highlight, 'test')}%> <%= link_to_function("fade"){|page| page.visual_effect(:fade, 'test')}%>
もう予想した通りの動きになります。サンプルも適当に作ってみました。
http://untitled-5ed05c.heroku.com/rjs_sample/
(*IEで見るとひどいことになりますが、これはHerokuがIEに対応してないからです。
どんなことができるのか
prototype+scriptaculousでできることは基本的にできる!(はず
基本的なものならreplace、remove、insert
エフェクトならAppearとかBlindDownとかその他もろもろ。
メインはJavascriptからコントローラにリクエストを飛ばして処理をすることだと思うけど(当然できます)それはまた今度!
Rails2以上でweborbを使う
基本は以前のと同じなんですが
何も設定せずに使うとこいつが起こると思います
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
ごにょごにょ...
サーバーログにそんなの出てないけど動かないよ!
というときは/log/-.logファイルを見る!
Rails2系から、authenticity_tokenを持たないPOSTリクエストは上記のエラーではじかれてしまうわけですが、シリアライズされたオブジェクトは当然POSTで渡ってくるわけで…。
flashから送られたリクエストをきゃーっちできないわけです。
ということでとりあえずこれで回避!
class WeborbController < ApplicationController protect_from_forgery :except => [:index]
もっといい方法あったら教えてください!
追記
form_authenticity_tokenでauthenticity_tokenの値を取得できるっぽいので。
- swfにauthenticity_tokenの値を送る
- swfからweborbへのリクエストにauthenticity_tokenを付与する
にしてみた。特に問題なく動く。
そういえば最近、ぐいぐいな画面を作るためにFlexやらRJSやらを使っているんだけど
RJSすごいよ!きもいよ!javascript1行も書いてないけどAjaxできちゃうよ!
HTMLソースはひどいことになってるけどそんなの気にしない!
Rubyのクラスの概念がわかった気になる一文
まずRubyにおいてクラス名とは定数名と同義である。ではクラス名と同名の定数には何が入っているのか。実は、クラスが入っている。Rubyではプログラムがさわれるものは全てオブジェクトだったから、クラスも当然オブジェクトとして表現されている。これをクラスオブジェクトと呼んでおこう。全てのクラスオブジェクトはClassクラスのインスタンスである。
つまりclass文とは、新しいクラスオブジェクトを作り、クラス名と同名の定数にそれを代入する、という操作である。一方インスタンスの生成とは、定数を参照し、そのオブジェクトに対してメソッド(普通はnew)を呼ぶ、という操作である。以下のような例を見ると、インスタンスの生成が普通のメソッド呼び出しとなんら変わらないことがよくわかるだろう。
第1章 Ruby言語ミニマム
正直イマイチ理解しきれていない…。
だけど、「Rubyは完全なオブジェクト指向である」というのは
単にプリミティブがない、ということでないらしい。
またそのうち書く!
関係ないけど、引用元サイトのドメインがすごい(笑
ネストしたリソース定義
Railsレシピのままなんですけどね。補足的な意味合いで書いてみる。
root/blog/1/entries
みたいな感じで blog_id = 1 にひもづくentryの一覧を表示する画面を作りたいとする。
まず、root.rbに
map.resources :blogs, :has_many=>:entries
と書くことによって、以下が追加される。
blog_entries GET /blogs/:blog_id/entries {:action=>"index", :controller=>"entries"} formatted_blog_entries GET /blogs/:blog_id/entries.:format {:action=>"index", :controller=>"entries"} POST /blogs/:blog_id/entries {:action=>"create", :controller=>"entries"} POST /blogs/:blog_id/entries.:format {:action=>"create", :controller=>"entries"} new_blog_entry GET /blogs/:blog_id/entries/new {:action=>"new", :controller=>"entries"} formatted_new_blog_entry GET /blogs/:blog_id/entries/new.:format {:action=>"new", :controller=>"entries"} edit_blog_entry GET /blogs/:blog_id/entries/:id/edit {:action=>"edit", :controller=>"entries"} formatted_edit_blog_entry GET /blogs/:blog_id/entries/:id/edit.:format {:action=>"edit", :controller=>"entries"} blog_entry GET /blogs/:blog_id/entries/:id {:action=>"show", :controller=>"entries"} formatted_blog_entry GET /blogs/:blog_id/entries/:id.:format {:action=>"show", :controller=>"entries"} PUT /blogs/:blog_id/entries/:id {:action=>"update", :controller=>"entries"} PUT /blogs/:blog_id/entries/:id.:format {:action=>"update", :controller=>"entries"} DELETE /blogs/:blog_id/entries/:id {:action=>"destroy", :controller=>"entries"} DELETE /blogs/:blog_id/entries/:id.:format {:action=>"destroy", :controller=>"entries"}
こうすることによって、例えばroot/blog/1/entriesにアクセスした場合。
entryコントローラのindexアクションではparams[:blog_id]によって、ブログのidを取得できるようになる。
blog_id=1 かつ entry_id=2のshowへのpathの作成は以下の通り
blog_entry_path(blog_id, entry_id)
ちなみに僕は、indexコントローラでblogを取得し、以下のように書きました
<% for entry in @entries %> <tr> <td><%=h entry.title %></td> <td><%=h entry.content %></td> <td><%= link_to 'Show', blog_entry_path(@blog, entry) %></td> <td><%= link_to 'Edit', edit_blog_entry_path(@blog, entry) %></td> </tr> <% end %>