Ruby on Rails

1.2と2.0が混在しているなー ちゃんと分けないと...
2.2がでましたね。Ruby 1.9に対応したか!速くなるかな?
国際化されたRails 2.2登場、スレッドセーフとRuby 1.9対応

NEWS

2008/10/22
Rails、PHPもサポートするフリーの統合開発環境「NetBeans IDE 6.5」RC版リリース

環境

http://rubygems.rubyforge.org/wiki/wiki.pl?RubyGemsよりRubyGems?をインストールしておきます。http://gesource.jp/programming/webgen/01.htmlのOne-Click Installerからでもインストールできます。

wget http://rubyforge.org/frs/download.php/5208/rubygems-0.8.11.zip
unzip rubygems-0.8.11.zip
cd rubygems-0.8.11
ruby setup.rb

あら?つながらなくなってますね。上記URLはつながらなくなってますね。ではこちらよりダウンロードします。http://rubyforge.org/frs/?group_id=126

wget http://rubyforge.org/frs/download.php/17190/rubygems-0.9.2.tgz
tar xzvf cd rubygems-0.9.2
ruby setup.rb

いまは1.0.1ですね。(2007-12-20)ではRailsもインストールしておきましょう。

gem install rails --include-dependencies

最新にする場合は、

gem update rails

windowsはRailsインストールを参考に
まず、RubyGems?http://docs.rubygems.org/のダウンロードより、rubygems-1.0.1.tgzをダウンロード rubyのディレクトリに展開後、(例:H:\ruby\rubygems-1.0.1)

cd H:\ruby\rubygems-1.0.1
ruby setup.rb

この後進んで、

As of RubyGems 0.8.0, library stubs are no longer needed.
Searching $LOAD_PATH for stubs to optionally delete (may take a while)...
...done.
No library stubs found.

H:\ruby\rubygems-1.0.1>

で終わり。zlib.dllがいる場合があるらしいので、そのときはH:\ruby\binにでもほりこんでおきます。 さてgemがはいったので、railsをいれましょう。

gem install rails --include-dependencies

んーSSLEAY32.dllやLIBEAY32.sllがないといわれましたね。OpenSSL for Windowsよりopenssl-0.9.8e-win32-bin_dynamic.zip をダウンロードして、解凍すればありますので、ruby\binにでもほりこんでおきましょう。あっそろそろwindowsがいやになってきた... ん?

Installing ri documentation for rake-0.8.1...
Installing ri documentation for activesupport-2.0.2...
Installing ri documentation for activerecord-2.0.2...

2.0になっていたのか。 ほかにiconvreadlineは入れておきましょう。 readlineは解凍して、binにreadline.dllをコピーします。でないとruby script/consoleとしても、

c:/ruby/lib/ruby/1.8/i386-mswin32/readline.so: 126: 指定されたモジュールが見つかりません。
  - c:/ruby/lib/ruby/1.8/i386-mswin32/readline.so (LoadError)

とかってエラーがでます。

ではDEMOを動かしてみましょう。適当なディレクトリで、

rails demo
cd demo
ruby script/server

デフォルトでポート3000をつかってWEBrickが起動しますので、ブラウザから確認してみてください。WEBrickはRubyのみで書かれたWebサーバでRubyとともにインストールされています。ちなみにdemoで

ruby script/generate controller コントローラ名

とするとMVCのコントローラが作成されます。コントローラ名は頭大文字後小文字です。そのかなにメソッドをつくり、app/views/コントローラ名/メソッド名.rhtmlをUTF-8で保存すると動きました。http://localhost:3000/コントローラ名/メソッド名 また実行して

no such file to load -- sqlite3

ってエラーが出た場合は、

gem install sqlite3-ruby 

とします。それでもエラーが出る場合は、http://sqlite.org/download.htmlよりsqlite-3_5_5.zipとsqlitedll-3_5_5.zipをダウンロード(windowsの場合) 適当な場所に展開して、同一ディレクトリにコピー後パスを通します。database.ymlの設定がsqlite3になっているので、別のDBに変えてもOKです。 mysqlでも同じようなエラーがでました。leopardの場合は、

env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql5/bin/mysql_config

アップデイト

gem update --system
gem update

Apache

FastCGI

ApacheのFastCGIを参考に先にいれて、実行したら、

RailsFCGIHandler(NameError)

とlog/error_logに出力されていたので、先を参考に(参考http://www.ruby-forum.com/topic/56459 )
gemは下のRuby on Railsを参考にしてください。

gem install fcgi 

一応httpdを再起動して、railsのプロジェクトを作ったら、そのアプリケーションの中のpublic/.htaccessを修正します。

#RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

また必要に応じて

#RewriteBase /test

を書き換えましょう。ここで私がはまった愚かなことがあります。いくら動かしても

execle() failed: No such file or directory

(2)No such file or directory: FastCGI:

と表示され全く動きませんでした。cgiにしても動かない。これはFastCGIの問題じゃないやんかと思い、悩んでいると、publicの中に

dispatch.cgi
dispatch.fcgi

と2つのファイルがあります。cgi? そういえればwindowsでつくったやつをそのままコピーしな。と思い中を覗いてみると、 先頭に

#!c:/ruby/bin/ruby

なんだこれは...

#!/usr/local/bin/ruby

に書き換えると動き出しました..... さてrails2を試してみると、ん?今度は

Invalid command 'RewriteEngine', perhaps mis-spelled or defined by a module not included in the server configuration

なんてエラーがでているな。これはmod_rewriteが入ってなかったので入れました。すると今度は

FastCGI: comm with (dynamic) server "/www/public/dispatch.fcgi" aborted: (first read) idle timeout (30 sec)

これじゃよくわからんので、わからんときはWEBrickで

ruby script/server

とするとと、

/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- gettext/rails (MissingSourceFile)

gettext入ってないないか。入れた覚えはないもんな。では入れましょう。http://rubyforge.org/frs/?group_id=855より

wget http://rubyforge.org/frs/download.php/31658/gettext-1.90.0.gem
gem install gettext-1.90.0.gem

やっと動きました。 さてこのままwebrootにコピーしちゃうと、configとかdbが丸見えなんでそれはいかんでしょうってことで、webrootを仮に/webroot/usera/rootってすると /webroot/usera/rubyを作ってそこに一式をコピーし(仮にプロジェクトをrubytest)、httpd.confに

Alias /rubytest/ "/webroot/usera/ruby/rubytest/public/"
<Directory "/webroot/usera/ruby/rubytest/public">
   Options +ExecCGI
   AllowOverride all
   Order allow,deny
   Allow from all
   AddHandler fastcgi-script .fcgi
</Directory>

ってやって、.htaccessのRewriteBaseを/rubytestとしてやりました。

参考:Ruby-GetText-Package
apache に redMine をインストールの Tips

Mongrel

FastCGIは確かに早いが、評判がよろしくない。apache2で動いてあまり変な動きはしてないがちょっと見合わせたほうがよさそうってことで、 MongrelをいれてApacheと連携しましょう。

gem install mongrel --include-dependencies

とるすと、linuxなんで、

Select which gem to install for your platform (i686-linux)
1. mongrel 1.1.4 (x86-mswin32-60)
2. mongrel 1.1.4 (java)
3. mongrel 1.1.4 (ruby)
4. mongrel 1.1.3 (ruby)
5. mongrel 1.1.3 (i386-mswin32)
6. mongrel 1.1.3 (java)
7. Skip this gem
8. Cancel installation
> 3
Select which gem to install for your platform (i686-linux)
1. fastthread 1.0.1 (mswin32)
2. fastthread 1.0.1 (ruby)
3. Skip this gem
4. Cancel installation
> 2

としました。

gem install mongrel_cluster

も入れておきます。 ではちょっと起動して見ましょう。

mongrel_rails start -p 8000 -e production -c /webroot/ruby/railstest -d --prefix /railstest

引数の-pはポート、-eはRails environmentなんで指定しなければdevelopment、-cでカレントディレクトリの指定、-dでデーモンで起動、--prefixでurlです。

Rails requires RubyGems >= 0.9.4 (you have 0.9.2). Please `gem update --system` and try again.

ん?エラーだ。では指示通りに、

gem update --system

gettextは上記のFastCGIを参考にして、入れておきましょう。では再度起動して動きました。 では終了してみましょう。

mongrel_rails stop -P /webroot/ruby/railstest/log/mongrel.pid

さて動作したんで、次はリバースプロキシの設定です。mod_proxyでやってみましょう。参考:Apache モジュール mod_proxy httpd.confに

ProxyRequests Off

<Proxy *>
Order deny,allow
Allow from all
</Proxy>

ProxyPass /railstest http://192.168.1.1:8000/railstest
ProxyPassReverse /railstest http://192.168.1.1:8000/railstest

を追加して再起動です。ではクラスタで複数起動するときは

mongrel_rails cluster::configure -N 2 -p 8000 -e production -c /webroot/ruby/railstest -d --prefix /railstest
mongrel_rails cluster::start

です。apache2.2だと、mod_proxy_balancerが使えるので、参考:Apache モジュール mod_proxy_balancer

<Proxy balancer://rails-app/>
       BalancerMember http://192.168.1.1:8000/railstest loadfactor=10
       BalancerMember http://192.168.1.1:8001/railstest loadfactor=10
</Proxy>

ってやるとバランサーになります。そういえば、

Ruby version is not up-to-date; loading cgi_multipart_eof_fix

ってエラーがでたことがあります。Rubyのバージョンが古いとのこと。あげとくか。 Mongrel HOWTO Pound + Mongrel + Apache2.0 で Ruby on Rails!
Mongrelを使ってみる。
CentOS5上でRuby on RailsアプリをApacheで動かす

LiteSpeed?

速いらしいが調査中
開発~運用Webサーバの比較

Passenger

本命はこいつか?Mongrelもいいですよ。

gem install passenger
passenger-install-apache2-module

インストールするとメッセージが表示されていますので、それにあわせてhttpd.confを修正しましょう。ちなみに下記はleopardで実行した時のメッセージです。

LoadModule passenger_module /Library/Ruby/Gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.so
RailsSpawnServer /Library/Ruby/Gems/1.8/gems/passenger-1.0.1/bin/passenger-spawn-server
RailsRuby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
<VirtualHost *:80>
    ServerName www.yourhost.com
    DocumentRoot /somewhere/public
</VirtualHost>

またRailsをさらに加速するテクノロジー「Ruby Enterprise Edition」なんてなもんも あるようで、1.9でRailsが動いてくれるまでなんとかしのぐか。

Passenger users guide
チェック必須!Rails新時代の到来か?「Passenger(mod_rails for Apache)」

Railties

Railsを利用するためのユーティリティです。

script/generate ジェネレータ ひな形作成
 model モデル
 scaffold モデル名 コントローラ名 アクション名  # モデル名必須 これでCRUD操作ができる
 controller コントローラ
 migration マイグレーション

migrate

テーブル作成

class CreateProducts < ActiveRecord::Migration
 def self.up
   create_table :products do |t|
     t.column :title, :string, :limit=>100, :null => false
     t.column :description, :string
     t.column :image_url, :string, :limit=>200, :null => false
     t.column :price, :integer, :null => false
   end
 end
 def self.down
   drop_table :products
 end
end

カラム追加

class AddDateAvailableToProduct < ActiveRecord::Migration
 def self.up
   add_column :products,:date_available,:datetime
 end
 def self.down
   remove_column :products,:date_available
 end
end

developmentではなくproductionに適用したい場合は、EclipsのRakeタスクの場合、直接

RAILS_ENV=production db:migrate

と打ち込んでリターンで実行されます。

Ruby on Rails で使えるデータ型
MigrationによるDB管理

database.yml

どんな記述が追加出来るか調べていました。

development:
 adapter: mysql
 database: hoge_development
 username: hogeuser
 password: hogepass
 host: 192.168.1.1
 port: 3306
 encoding: utf8
 timeout: 5000

environment.rb

本番にDBを切り替える

# ENV['RAILS_ENV'] ||= 'production'

ENV['RAILS_ENV'] ||= 'production'

としてやります。 productionに設定すると、サーバー(httpd,mongrel等)を再起動しないとコードの変更は反映されないので、注意

ActiveRecord?

参考:RubyOnRails を使ってみる 【第 3 回】 ActiveRecord
ザリガニが見ていた...。さんのページは とても参考になります。このような方がお近くにおられれば..とよく思います。

項目命名規約

datetime _atで終わる
date _onで終わる
外部キー ターゲットのクラス名を小文字に変えて_idをつける

テーブル名を変更する

def self.table_name() "tablename" end

もしくは

set_table_name  "tablename"

find

idでの検索では見つからない場合、エラーとなるので捕捉してやる必要があります。

product = Product.find(params[:id])
rescue ActiveRecord::RecordNotFound
   flash[:notice] = "そんなIDはない"

とか、

product = Product.find(params[:id])
rescue => ex
	flash[:notice] = ex.message

とか。

トランザクション

ActiveRecord::Base::transaction() do

rascue

end

って書き方もできるのか..

http://underrails.seesaa.net/article/54762314.html

has_many

べたで書いた場合

has_many :data1,
           :class_name => "Data1",
           :finder_sql => 'select data1.* from data1,data2 where data2.id = data1.koumoku_id and data1.id = #{id}'

ダブルクォーテーションではなくシングルクォーテーションで またファインダメソッドを使って

 has_many :specific_lineitems,
           :class_name => "lineitem" do
             def get(id)
               find :all,:conditions=>['order_id = ?',id]
             end
           end

とかってしてやって、

p order.specific_lineitems.get(hoge)

としてやることもできる。

p order.lineitems.find(:first,:conditions =>["order_id=?",hoge])

でいいのですが。なんか変な感じだと思っていると、order.findで子のlineitemsの条件が書き方がわからんからだー もちろんWHERE order_id = ?ではなく、LEFT OUTER JOINに。 仮に書けたとして、includeは書けるのか? この辺は再調査だな。でもこんなの見つけてしまったということはだめなのか?
[Ruby on Rails]:include の JOIN 節に condition を追加したい。
さて同容に孫でソートしたい場合はどうするのか?

has_many :lineitems,:include=>"lineitem",:order => "lineitems.cdkoukou"

としてやればできた。このorderは複数なのか。

has_manyでテーブル関連付けをしたときのDB更新
関連とDBへの保存のタイミングを整理する

find_by_sql

@table1 = Table1.find_by_sql("select table2koumoku1 from table2")

このfind_by_sqlはTable1と関係ないtable2でのsqlを使っても取得できた。

<% for table1 in @table1 -%>
<tr>
 <td><%= h(table1.table2koumoku1) %></td>
</tr>
<% end -%>

これは逃げ道になりそう?またパラメータを渡す場合は、

aaaa = "11"
@table1 = Table1.find_by_sql("select table2koumoku1 from table2 where table2koumoku1 = ?",aaaa)

とか

@table1 = Table1.find_by_sql(["select table2koumoku1 from table2 where table2koumoku1 = :id and table2koumoku2 = :id2",{:id => params[:id],:id2 => params[:id2]}])

他に

params = {}
params[:para2] = "2"
params[:para1] = "1"
find(:all,:conditions => ["code_id = :para1 and image_url = :para2",params],:order => "title")

とすると

SELECT * FROM `products` WHERE (code_id = '1' and image_url = '2') ORDER BY title

となるので、動的にSQLも書けることでしょう。

connection.select_all

もうひとつの逃げ道として(逃げてばっかりですが..)、コントローラで

@datas = Table1.connection.select_all("select * from table2")

として、

<% @datas.each{|value|  -%>
<tr>
 <td><%= h(value['table2koumoku1']) %></td>
</tr>
<%} -%>

destroyとdeleteの違い

deleteはコールバックと検証を迂回していき、直接deleteだけになり、dependentとかもよびだされません。 destroyはすべて呼び出してくれます。ですので通常はdestroyのほうがいいでしょう。

コード管理

漢には笑わせてもらいました。 いまこそ ARと外部キーについて考える (舞波)

SQL確認

ActiveRecord?が生成するSQLは、logディレクトリに出力されています。EclipseですとNTailというプラグインがありますので、 それで確認できます。

リンク

Rails RecipeBookはてな版(多対多の関連を設定する)
「SQL書き方ドリル」のスキーマをActiveRecordで書く

ActiveScaffold?

優しいRailsの育て方 この本はおもしろかったです。早く2版でないものでしょうか。

GetText?

エラーを日本語化したい場合、ActiveHeart?よりこっちみたいな記事があったので、試してみます。

c:\ruby>gem install gettext
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続でき
ませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗し
ました。 - connect(2) (Errno::ETIMEDOUT)
       getting size of http://gems.rubyforge.org/Marshal.4.8

ん?なんだ。ファイアーウォールではじかれていたのか。では設定です。 config/environment.rbの最初に

$KCODE='u'          # u=utf s=Shift_JIS, e=EUC-JP
require 'jcode'  

とし、最後に

require 'gettext/rails'

記述します。またapp/controllers/application.rbに

init_gettext "hogedom"

とテキストドメインの名前を記述しておきます。この名前はDBの項目を日本語化するときにも出てきます。 では翻訳文字を抽出する為にlib/tasksにrakeタスクをつくります。とりあえず名前はgettext.rakeで

desc "Update pot/po files."
task :updatepo do
 require 'gettext/utils'
 GetText::ErbParser.init(:extnames => ['.rhtml', '.erb'])
 GetText.update_pofiles(
   "hogedom",  #<<<<<<テキストドメインの名前
   Dir.glob("{app,config,components,lib}/**/*.{rb,rhtml,rjs,erb}"),
   "hogedom 1.0.0")  #バージョン
end

desc "Create mo-files"
task :makemo do
 require 'gettext/utils'
 GetText.create_mofiles(true, "po", "locale")
end

では実行しましょう。

rake updatepo

するとpoディレクトリが作成され、その中にテキストドメイン名のrailsproject.potができました。 これをpo/jaディレクトリを作成して、そこにコピーして、railsproject.poにリネームします。

po/ja/railsproject.po

中を見ると、たとえば

#: app/models/product.rb:-
msgid "Product|Title"
msgstr ""

てな感じになっているので、

#: app/models/product.rb:-
msgid "Product|Title"
msgstr "タイトル"

とか日本語を入れてやります。設定後、

rake makemo

でエラー表示の時に項目名も日本語化されます。ではコントローラのメッセージは?ということで

 def create
   @code = Code.new(params[:code])

   respond_to do |format|
     if @code.save
       flash[:notice] = 'Code was successfully created.'

とかありますが、

       flash[:notice] = 'Code was successfully created.'

       flash[:notice] = _('Code was successfully created.')

にしてやり、po/ja/railsproject.poに

#: app/controllers/codes_controller.rb:-
msgid "Code was successfully created."
msgstr "登録成功!"

としてやった後にrake makemoです。ではviewも

 <p>
   <%= f.submit 'Update' %>
 </p>

 <p>
   <%= f.submit _('Update') %>
 </p>

として、po/ja/railsproject.poに

msgid "Update"
msgstr "更新!"

これってmsgidってどこでも使えるですね。

ついでに、

class Code < ActiveRecord::Base
 validates_presence_of :codekn,:code,:message => "%{fn}は必須!"
 set_error_message_title("%{record}にエラーがある。", "%{record}に%{num}個もエラーが...")
 set_error_message_explanation("以下のエラーを確認せよ!", "ちょっとエラーが多いよ....")
end

とすると、

コードテーブルに2つのエラーが発生しました。

次の項目を確認してください。

   * コードを入力してください。
   * コード区分を入力してください。

ってメッセージが

コードテーブルに2個もエラーが...

ちょっとエラーが多いよ....

   * コードは必須!
   * コード区分は必須!

Ruby-GetText-Packageとは?
Ruby on RailsでRuby-GetText-Packageを使う
Ruby on Rails]2.0でRuby-GetTextを使う
MacOS X10.5 Leopard環境にRuby-GetTextをインストールする
GetTextで日本語化してみる。
Ruby-GetText初体験その6【po ファイルと mo ファイル】

デバッグ

p オブジェクト名

とすると、コンソールに表示されれるので確認

<%= debug(params) %>

Railsでデバッグをする7つの方法

TIPS

とりあえず

app/controllers/コントローラ名_controller.rb

class コントローラ名Controller < ApplicationController
 def メソッド名
   @test = "へへっへ"
 end
end

メソッド名.rhtml

<html>
	<head>
		<title>ほほほほー</title>
	</head>
	<body>
		<% 3.times do |count| %>
			<h1><%= count %>ひっひ-</h1>
			<%= @test %>
		<% end %>
	</body>
</html>

ここで、JSPみたいにRubyのコードを<%で埋め込んでますが、JSPみたいなもんです。

さてscaffoldをつかったらエラーがでました。Ruby on Rails2.0から変わったんですね。

undefined method `scaffold' for AdminController:Class

その対象のプロジェクトのディレクトリで、

ruby script/plugin install scaffolding 
ruby script/plugin install http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/classic_pagination/ 
ruby script/plugin install http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/will_paginate/

また登録したとき

ActionController::InvalidAuthenticityToken

ってでる。これも2.0からで外部から来たリクエストであればはじくようになっているそうなのだが、おそらくscaffoldがCSRFの対策をしてなくて、hiddenを埋め込んでいないからだろう。ってことで、Controllerに

skip_before_filter :verify_authenticity_token

を追加してやるとskipしてくれます。 また実際に動かしてみると、登録時に日本語で落ちる場合は、

ActiveRecord::StatementInvalid in ...

config/database.ymlにencoding:の指定を追加しましょう。dbの文字コードとあわせておきます。Rails2.0からはscaffoldが

script/generate scaffold book

から

script/generate scaffold book title:string price:integer

みたいにモデル名に後にフィールド名と:データ形式を追加するんですね。 ん?生成されたコントローラを見ると、

respond_to do |format|
 format.html # index.html.erb
 format.xml  { render :xml => @books }
end

ってあります。これって2.0からか。http://wota.jp/ac/?date=20060317#p01を参考に

参考:■[Ruby on Rails]2.0のscaffoldから書き直してみる

ルートページの設定

config/routes.rbに

# You can have the root of your site routed with map.root -- just remember to delete public/index.html.
# map.root :controller => "welcome"

とかってありますので、

map.root :controller => "login", :action=>"login"

とかに変更して、public/index.htmlを消しておきます。

部分テンプレート

頭にアンダーバー(_)をつける。

<%= render(:partial => "cartitem",:collection => @cart.items) %>

このような場合、_cartitem.html.erbという部分テンプレートをしようすることになる。 またここではcollectionにセットをしている為、_cartitem.html.erbはそのcollectionの要素数分(@cart.items.size)回る。 _cartitem.html.erbではこのcollectionの要素はcartitemでアクセスできる

<li><%= h(cartitem.quantity)%>個<%= h(cartitem.price)%>円 <%= h(cartitem.title)%></li>

みたいに。このcollectionは他にもobjectとか指定可能

cycle

<%= cycle(i, "") -%>

とかって書けば、一つとばしに出力されるのかなーと思っていたけど、値が変わる場合はだめでした。 そりゃそうか。
cycleヘルパーを使ってテーブルをストライプにする

スクリプト

rails プロジェクト名   #プロジェクト作成
ruby script/server -e development(test,production) #サーバ起動
ruby script/generate scaffold モデル名 コントーラ名 ※2.0違います。
ruby script/generate ajax_scaffold モデル名 コントーラ名 ajax
ruby script/generate controller コントローラ名  #コントローラ作成
ruby script/generate model テーブル名   #モデル作成 単数形で
ruby script/destroy ファイル削除
ruby script/runner メソッドをコンテキスト外で動かすことができるみたい。

コールバッグフック

def before_create #保存前にフック
def after_create #保存後にフック
def before_destroy #削除前にフック

チェック

必須チェック

validates_presence_of :項目

ユニーク

validates_uniqueness_of :項目

ここで項目が2つでユニークって場合で,たとえばhoge1の中でhoge2は重複したらだめという場合は、

validates_uniqueness_of :hoge2,:scope => :hoge1

ん?3つの場合はどうすんだ?

validates_uniqueness_of :hoge3, :scope => [:hoge1, :hoge2]

でいいのか。 数値チェック

validates_numericality_of :項目  

ActiveRecord::Validations::ClassMethods
Rails1.2.3 ActiveRecordで日付チェック(Validates Multiparameter Assignmentsプラグイン)

モデルにエラーを追加する場合

model.errors.add_to_base("エラーを追加")

collection_select

<%= collection_select("user",user.code,@users,"code","name",{:include_blank => true})%>

とかしてもうまくselecedがついてくれないので、とりあえず、ApplicationHelper?

 def select_ext (strName,strCode,arrData,value,outdata,isBlank)
   strReturn = '<select id="'+strName+'_'+strCode+'" name="'+strName+'[' + strCode + ']">'
   if isBlank == true
     strReturn += '<option value=""></option>'
   end
   for oneData in arrData
     if (strCode == oneData[value])
       strReturn += '<option value="'+oneData[value]+'" selected="selected">'+oneData[outdata]+'</option>'
     else
       strReturn += '<option value="'+oneData[value]+'">'+oneData[outdata]+'</option>'
     end
   end
   strReturn += "</select>"
   return strReturn
 end

とかしてviewから呼び出して逃げてます.. はやく調べんと..

codes = Code.find(:all,:order => "id").map {|u| [u.nmname,u.id]}
f.select(:code_id,codes,{:include_blank => true})

と思ったらあっさりOK。

codes = Code.find(:all,:order => "id")
f.collection_select(:code_id,codes,:id,:code,{:include_blank => true})

もOK。

f.collection_select(:code_id,Code.find(:all,:order => "id"),:id,:code,{:include_blank => true})

でもOK。書式は

collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})

なので、

f.collection_select(:code_id,Code.find(:all,:order => "id"),:id,:code,{:include_blank => true},{"name"=>"hohogee"} )

と指定できる。

collection_selectselect, Rails のコンボボックス(select)を生成する時の tabindex 属性の指定の仕方について を参照

複数のsubmitボタン (2.0)

とりあえず、やってみた。viewで

<%= f.submit 'ボタン1',:name=>'aa' %>
<%= f.submit 'ボタン2',:name=>'aa2' %>

で、controllerで

 def update
   unless params[:aa].nil?
     p "aa != nil";
   end
   unless params[:aa2].nil?
     p "aa2 != nil";
   end

ただこれ、disable_withを指定するとparamsにセットされなくなるな。なんでだ? 同一フォームに複数のイメージ送信ボタン
http://www.fdiary.net/ml/rails/msg/207 リンクきれてるな~

複数モデルの保存 (2.0)

では早速サンプルを。ついでに複数ボタンも

<% form_tag(:action => 'update1') do %>
	<% for @code in @codes %>
		<%= text_field("code[]", 'nmname') %><br>
	<% end %>
	<%= submit_tag 'こっちだけ更新',:name=>'aa1' %>
	<%= submit_tag 'なにもしない',:name=>'aa2' %>
<% end %>

この2行目でcodeを@codeとインスタンス変数にして、 3行目でcodeに[]をつけてやってます。するとhtmlは

<form action="/codes/update1" method="post">
 <input id="code_1_nmname" name="code[1][nmname]" size="30" type="text" value="ddd" /><br>
 <input id="code_2_nmname" name="code[2][nmname]" size="30" type="text" value="bdddd" /><br>
 <input id="code_3_nmname" name="code[3][nmname]" size="30" type="text" value="cfffff" /><br>
 <input name="aa1" type="submit" value="こっちだけ更新" />
 <input name="aa2" type="submit" value="なにもしない" />
</form>

と生成してくれます。ではcontrollerで

 def update1
   #p params
   unless params[:aa1].nil?
     params[:code].each{|key,value|
       Code.update(key,:nmname => value[:nmname])
     }
   end
   redirect_to :action => 'index'
 end

とすれば更新できます。

params[:code].each{|key,value|
   Code.update(key,:nmname => value[:nmname])
}

Code.update(params[:code].keys,params[:code].values)

と簡単に記述できます。
form_forをつかってみましょう。ついでにform_forに適当なhogeを設定しておいて、

<% form_for :hoge, :url => {:action => 'update1'} do |f| %>
	<%= f.text_field :nmname %><br>
	<% for @code in @codes %>
		<%= text_field("code[]", 'nmname') %><br>
	<% end %>
	<%= submit_tag 'こっちだけ更新',:name=>'aa1' %>
	<%= submit_tag 'なにもしない',:name=>'aa2' %>
<% end %>

でhtmlは

<form action="/codes/update1" method="post">
	<input id="hoge_nmname" name="hoge[nmname]" size="30" type="text" /><br>
	<input id="code_1_nmname" name="code[1][nmname]" size="30" type="text" value="dddd" /><br>
	<input id="code_2_nmname" name="code[2][nmname]" size="30" type="text" value="bddddfd" /><br>
	<input id="code_3_nmname" name="code[3][nmname]" size="30" type="text" value="cfffffa" /><br>
	<input name="aa1" type="submit" value="こっちだけ更新" />
	<input name="aa2" type="submit" value="なにもしない" />
</form>

ちゃんとidやnameにhogeがつきました。ちなみにselectの場合は、

<%= collection_select("code[]", 'code',@codes,:code,:nmname) %>

でいけるので、同じです。

参考
1アクションで複数のモデルを同時に保存するには?
A Day In The Life(Railsで複数行更新)
ぺんちゃん日記(text_fieldなどのフォームを配列化する)

paginate (1.2)

モデルに対しては

@pages, @users = paginate(:users, :order_by => 'usercode')

とかすればいいのだが、そんな単純なケースでない場合、Paginatorを使うことになる。http://wota.jp/ac/?date=20050629にも書かれていますが、ほんとpaginate_by_sqlてなものがほしいです。

per_page = 5
@tmp = Jikanwari.find_by_sql(["select count(*) as cnt from jikanwari where youbi <> ?","7"])
count = @tmp[0].cnt.to_i
@pages = Paginator.new(self, count, per_page, @params['page'])
@jkanwaris = Jikanwari.find_by_sql(["select * from jikanwari where youbi <> ? LIMIT ? OFFSET ?", "7", per_page, @pages.current.to_sql[1].to_i])

でviewに

<%= pagination_links(@pages) %>

paginate(2.0)

classic_pagination を will_paginateに置き換えてみた。

フィルター

before_filter :メソッド名1 :except => :メソッド2

メソッドの呼び出し前にメソッド名1を呼び出します。ただしメソッド2は除きます。

フォームヘルパー

  • form_tag
    <%= form_tag :controller => 'conta',:action => 'touroku' %>
    さて2.0にすると、
    undefined local variable or method `end_form_tag' for #<ActionView::Base:0x4e44aa4>
    とエラーが..end_form_tagはなくなったんですね。endです。
  • text_field_tag
    <%= text_field_tag("koumokumei", atai,options = {:maxlength=>3,:size=>3}) %>
    DBとか絡まない場合。 hiddenではhidden_field_tagがある。
  • button_to
    formを含んだsubmitボタンを生成します。formを含んだ? サンプルで確認しましょう。
    <% for product in @products -%>
    	<%=	product.title %><br>
    	<%= text_field_tag :title, product.title %><br>
    	<%= button_to "カーとに入れる",{:action=> :add_to_cart, :id=>product,:para1=>product.price},{:confirm => "Are you sure?"} %>
    	<hr>
    <% end %>
    このようにforでまわした場合は、どうなるかですが、
    	ひひい<br>
    	<input id="title" name="title" type="text" value="ひひい" /><br>
    	<form method="post" action="/store/add_to_cart/2?para1=1.0" class="button-to">
    		<div>
    			<input onclick="return confirm('Are you sure?');" type="submit" value="カーとに入れる" />
    			<input name="authenticity_token" type="hidden" value="601ad11f3a639c4de81b4c96485842f15ee51f26" />
    		</div>
    	</form>
    	<hr>
    	ほほー<br>
    	<input id="title" name="title" type="text" value="ほほー" /><br>
    	<form method="post" action="/store/add_to_cart/1?para1=100.0" class="button-to">
    		<div>
    			<input onclick="return confirm('Are you sure?');" type="submit" value="カーとに入れる" />
    			<input name="authenticity_token" type="hidden" value="601ad11f3a639c4de81b4c96485842f15ee51f26" />
    		</div>
    	</form>
    	<hr>
    となりました。para1とかはちゃんとformにくっついているんですが、このtext_field_tagに関しては、form内 にないです。ということは自分だけで完結するformとsubmitを用意してくれるヘルパーです。

コントローラ名取得

<%= controller.action_name%>

Ajax

まずjavascriptsを使えるようにしておきます。javascriptsはpublic/javascriptsにいます。html.erbを開いて

<%= javascript_include_tag :defaults %>

としておくと、

<script src="/javascripts/prototype.js?1204131898" type="text/javascript"></script>

みたいに生成されます。そして、

<% form_tag(:action => 'add_to_cart',:id=>product) do %>

とかなっているところを

<% form_remote_tag :url=>{:action=>:add_to_cart,:id=>product} do%>

とform_remote_tagに変更します。htmlは

<form action="/store/add_to_cart/3" method="post" onsubmit="new Ajax.Request('/store/add_to_cart/3', {asynchronous:true, evalScripts:true,
parameters:Form.serialize(this) + '&amp;authenticity_token=' + encodeURIComponent('da20420b9451c0hohohohohohohoho')});
return false;">

とできてます。このAjax.Requestはprototype.jsですね。parameters:Form.serialize(this)になっているので、formの要素を/store/add_to_cart/3に 送ってくれます。で、store_controllerのadd_to_cartメソッドが実行されますが、レンダリングでhtml.erbからrjsにします。このRJSはおもしろいので、 後でちゃんと勉強するとして、add_to_cart.rjsの中身は

page.replace_html("cartid",:partial=>"cart",:object=>@cart)

とした場合、雰囲気はrenderに似ていますが、要は部分テンプレートcartにあるcssのidがcartidの要素を置き換えてくれます。 @cartは部分テンプレートで使うオブジェクトになります。 ということは、store_controller#add_to_cartのレンダリングはadd_to_cart.rjsをつかってidの中身をおきかえてくれるんですね。 こりゃ便利!さらにデバッグはfirebugを使って、NetのXHRを選択すれば、追うことができます。

ajax_scaffoldを使う場合

gem install ajax_scaffold_generator

RJS

html.erbを

<%= javascript_include_tag :defaults %>
<div id="hoge">
	hoho
</div>

として、pageをrjsに書いてどうなるかみてみます。

<%= javascript_include_tag :defaults %>

をしておくと、public\javascripts配下のjsをインクルードしてくれてます。

<script src="/javascripts/prototype.js?1204131898" type="text/javascript"></script>
<script src="/javascripts/effects.js?1204131898" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js?1204131898" type="text/javascript"></script>
<script src="/javascripts/controls.js?1204131898" type="text/javascript"></script>
<script src="/javascripts/application.js?1203128030" type="text/javascript"></script>

後ろについている?1203128030は勝手につきます。おそらくブラウザにキャッシュされるのを防ぐためでしょう。

  • replace_html
    page.replace_html("hoge",:partial=>"cart",:object=>@cart)
    とすると、部分テンプレート_cartでhogeを置き換えます。ちなみに
    page.replace_html("hoge",:partial=>"cart",:object=>@cart,:locals=>{:hogepara=>'hogehoge'})
    とかしたら、部分テンプレート_cartで
    <%= hogepara %>
    とかで使えます。
  • insert_html
    page.insert_html :top,'hoge',"追加ーtop"
    page.insert_html :before,'hoge',"追加ーbefore"
    page.insert_html :after,'hoge',"追加ーafter"
    page.insert_html :bottom,'hoge',"追加ーbuttom"
    とすると
    追加ーbefore
    <div id="hoge">
    	追加ーtop
    	hoho
    	追加ーbuttom
    </div>
    追加ーafter
    FirefoxのDOM Inspectorで確認しました。
    page.insert_html :top,'hoge',content_tag("div", "追加ーtop")
    であれば、
    <div>追加ーtop</div>
    になります。ではテーブルに追加してみましょう。html.erbが
    <table>
    <thead><th>カラム名</th></thead>
    <tfoot></tfoot>
    <tbody id="target">
      <tr><td>ああああ</td></tr>
    </tbody>
    </table>
    として、
    page.insert_html :bottom, 'target', content_tag("tr", content_tag("td","だだだ"))
    とすると行が増えていきます。 参考:Ajax でテーブルへの追加
    またidとか指定する場合は、
    page.insert_html :bottom, 'target', content_tag(:tr, content_tag(:td,"だだだ",:id => :tr1))
    とできます。またシンボルに変更してます。
  • update
    page['hoge'].update('aaaa').show
    とすると、hogeがaaaaにupdateされます。
  • effect
    ActionView?::Helpers::ScriptaculousHelper?を使ってやるといろいろとエフェクトをかけれます。
    page.visual_effect :grow, :tr1,  :duration => 0.6
    やidをいきなり指定して、
    page[:currentitem].visual_effect :highlight,:startcolor => "#88f88",:endcolor => "#114411"
    とかするとエフェクトをかけれます。

参考:
RubyOnRails を使ってみる 【第 7 回】 RJS を使ってみる
RJSでテーブルを操作する時の注意
Rails RecipeBookはてな版

セッションをDBに

rake db:sessions:create

とすると

 create  db/migrate/XXX_create_sessions.rb

と作成されるので、

rake db:migrate

でsessionsテーブルができてます。そしてconfig/environment.rbを開いて

# config.action_controller.session_store = :active_record_store

config.action_controller.session_store = :active_record_store

としてやります。さてサーバ再起動で、

c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:478:
in `const_missing': uninitialized constant CGI::Session::ActiveRecordStore (NameError)
	from c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session_management.rb:24:
in `const_get'
	from c:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/session_management.rb:24:in `session_store='

ってエラーが出た... なんじゃ んー ではactiverecodeをつかってるいんだろうから、config/environment.rbのはじめのほうに

require 'active_record'

を追加。どうかな?おっ動いた!では実際にアプリを動かしてみると、

ActionController::InvalidAuthenticityToken in Store#index
No :secret given to the #protect_from_forgery call. 
Set that or use a session store capable of generating its own keys (Cookie Session Store).

んー ではメッセージにしたがってActionController?を見てみましょう。

protect_from_forgery # :secret => '11771fd07d754cc5380bdhohohhhoh'

これのとことか。コメントをはずしてやって

protect_from_forgery :secret => '11771fd07d754cc5380bdhohohhhoh'

すると動き始め、sessionテーブルを覗くと保存されています。 消したい場合は、

db:sessions:clear

Shift-JIS

Shitf-JISにこだわっているわけではなく、他の文字コードを使う場合は、どうするのかを調べていた。仮にDBをsjisにした場合、database.ymlに

encoding: sjis

を追記した。またenvironment.rbに

$KCODE = 's'

を追加してみたが、文字化けは変わらなかったので、 application.rbを

class ApplicationController < ActionController::Base
  # Pick a unique cookie name to distinguish our session data from others'
  session :session_key => '_rubytest_session_id'
  before_filter :set_charset
    private
    def set_charset
      headers["Content-Type"] = "text/html; charset=Shift-JIS"
    end
end

にすると表示されるようになった。しかし、これでやるとmodels/hogetable.rbで

validates_presence_of :title,:message => "に空はだめ"

とか日本語にすると落ちてしまうので、before_filterをやめて、environment.rbの最後に

$KCODE = 'SJIS'
ActionController::Base.default_charset = 'Shift_JIS'

としてやると日本語で出力されました。出力はされましたが、こんなことを全てに書いていてはどうしようもありません。

RUBY_HOME\gems\1.8\gems\activerecord-1.15.3\lib\active_record\validations.rb

にメッセージがあり、

@@default_error_messages = {
     :inclusion => "is not included in the list",
     :exclusion => "is reserved",
     :invalid => "is invalid",
     :confirmation => "doesn't match confirmation",
     :accepted  => "must be accepted",
     :empty => "can't be empty",

このあたりを書き換えれば、いけそうなんですが、それもどうかと思い、調べていると、new_errorsってなものがありました。http://wiki.rubyonrails.com/rails/pages/HowToWritePluginToModifyRailsCoreを参考に

ruby script/generate plugin new_errors

を実行し、

RUBY_HOME\depot\vendor\plugins\new_errors\init.rb

に、

require 'new_errors'

を追加して、

RUBY_HOME\depot\vendor\plugins\new_errors\lib\new_errors.rb

module ActiveRecord
 class Errors
   @@default_error_messages[:inclusion] = "is not included in the list ignoramus." 
   @@default_error_messages[:exclusion] = "is reserved. Pay attention!" 
   @@default_error_messages[:invalid] = "is invalid, moron.う" 
   @@default_error_messages[:confirmation] = "doesn't match confirmation. Pick something that does!"
   @@default_error_messages[:accepted ] = "must be accepted or it will not work." 
   @@default_error_messages[:empty] = "空は駄目よ" 
   @@default_error_messages[:blank] = "ブランクはいかん" 
   @@default_error_messages[:too_long] = "長すぎ (max is %d characters). IT IS TOO LONG!!!" 
   @@default_error_messages[:too_short] = "短すぎ (min is %d characters). t.o.o.s.h.o.r.t." 
   @@default_error_messages[:wrong_length] = "is the wrong length (should be %d characters). I'm sorry. That is an incorrect response." 
   @@default_error_messages[:taken] = "has already been taken by your mom." 
   @@default_error_messages[:not_a_number] = "数字じゃないやん. Numbers are things like 01234 ok?" 
 end
end

を追加して、修正して実行し、WEBrickを再起動すると、

@@default_error_messages[:blank] = "ブランクはいかん" 

new_errors.rb:10: Invalid char `\203' in expression (SyntaxError)

とエラーで立ち上がりません。んー UTF-8で保存するととりあえず、立ち上がりましたが、その場合は文字化け... では RUBY_HOME\gems\1.8\gems\activerecord-1.15.3\lib\active_record\validations.rb ではどうなんだろうと思い修正すると、うまく表示された.... 当分解決方法が見つかるまではこれでいこう... あとは

4 errors prohibited this product from being saved
There were problems with the following fields:

を何とか日本語にせんと。ん?Shift-JISからずれてきているような気が。あれ?http://jp.rubyist.net/magazine/?0012-RubyOnRailshttp://www.hackmylife.jp/archives/rails/を参照させていただくとActiveHeart?なるものがあるではないか。 こいつをvendor\plugins\active_heartにコピーして動かすと、あー日本語になった。もしやvendor\plugins\active_heart\lib\active_record_messages_ja.rbをShift-JISにすればいけるのかなと思い、やってみましたが、エラーで立ち上がりませんでした...
となると次に気になるのは項目名です。モデルに

class Product < ActiveRecord::Base
 set_field_names :title => 'タイトル', :description => '説明', :image_url =>'イメージURL',:price => '価格'

とかしてやると、(UTF-8で保存)、エラー時の項目名は、無事日本語になりました。リスト(list.rhtml)の方はどうかと思って見てみると、変わってないやん... そりゃそうか。

column.human_name

でタイトル表示しているからでした。

Product.human_attribute_name(column.human_name)

あれ?日本語化されんぞ? active_record_messages_ja.rbを見ていると、

   def human_attribute_name(attribute_key_name)
     if @field_names && @field_names[attribute_key_name]
       @field_names[attribute_key_name]
     else
       _human_attribute_name(attribute_key_name)
     end
   end

       _human_attribute_name(attribute_key_name)

に入ってる。ん?human_name? これって、先頭が大文字になっているからか。では、

Product.human_attribute_name(column.name)

にしてやれば、うまくタイトルが日本語で出力されました。さてこうなったらnew.rhtmlや、edit.rhtmlもやってしまいましょう。ん? edit.rhtmlを見ると、

<%= render :partial => 'form' %>

となってます。この:partialは部分テンプレートなので、ということはアンダーバーをつけた_form.rhtmlがいるはずなので、覗いてみると、げっ!ここはハードコーディングか...

<%= Product.human_attribute_name("title") %>

に変更しました。new.rhtmlも<%= render :partial => 'form' %>になっているので、かってに直っていることでしょう。

複数形の確認

Loading test environment (Rails 2.0.2)
>> "book".pluralize
"book".pluralize
=> "books"
>> "books".singularize
"books".singularize
=> "book"

YAML

YAMLを読み込む場合

yamlfile = YAML::load(File.open('hoge.yml'))

二重送信防止

disable_with

でボタン押下後、表記がかわる。たとえばボタン名称は検索だけど、 クリックすれば、処理中に変わる。

<%= submit_tag '検索',:name=>:seek,:disable_with=>"処理中..." %>

ただし、paramsには params[:seek]に'検索'って文字列がはいっていたが disable_withをつけるとそもそもparams[:seek]がない。んー

Oracle

http://wiki.rubyonrails.org/database-support/oracle

Mongrel Time out

朝webサーバにつなぐとまったくつながらず。Mongrelを再起動するとつながったのですが、production.logを見てみると

 Status: 500 Internal Server Error
 Mongrel timed out this thread: shutdown

apacheは

[Wed Apr 01 10:24:03 2008] [error] [client 192.168.1.1] proxy: error reading status line from remote server 127.0.0.1
[Wed Apr 01 10:24:03 2008] [error] [client 192.168.1.1] proxy: Error reading from remote server returned by /hoge

とエラーが発生しています。 どうも Rails + MySQL (+ Mongrel?) でDB接続の通信が無い状態が続くとデッドロックする。MySQLのinteractive_timeoutぽいのですが、MySQLのinteractive_timeoutとwait_timeoutに関係がありそうです。
うちの環境では、 /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/connection_specification.rb を見てみると、

@@verification_timeout = 0

になっていたんで、config/environment.rbに

ActiveRecord::Base.verification_timeout = 14400

を追記してます。mysql側は

show variables;

で確認すると、interactive_timeout、wait_timeoutともに28800でした。 mysqlのmy.cnfに

[mysqld]
wait_timeout=31536000
interactive_timeout=31536000

とすれば期間を延ばせるんですが、これは最終手段だよな~ 普通再度コネクトしなおすだけでいいような気がするんですが。

render、redirect_toの違い

単純にフォワード、リダイレクトだと思う。 リダイレクトとフォワードの違いを知る

未解決

class_eval

active_record_messages_ja.rbで使われていたのですが、?

datetimeが化ける

登録は普通にできるのですが、product.send(column.name)で表示してみると、そこだけ化けてしまいます。ブラウザの文字エンコーディングをshiftjisにしてみると見えるが、他の項目が化けてしまってます。正しい表示は、

Sun Mar 12 00:55:00 東京 (標準時) 2006

とりあえずかっこ悪いので、strftime("%Y/%m/%d %H:%M:%S")で逃げてます。

Mysql::Error: Lost connection to MySQL server during query:

たまにこのようなエラーがでる。とりえあず

gem install mysql

としていれてみた。

ERROR:  Error installing mysql:
       ERROR: Failed to build gem native extension.

ってエラーが出る場合は、

gem install mysql -- --with-mysql-dir=/usr/local/mysql

とかにしてみよう。 Lost connection to MySQL server during query
[Ruby on Rails] MySQLの Lost connectionエラー

TODO

早くext?と連携させたい~

Lipsiadmin
Ext plugin|

errors.reject

error_messages_forの編集方法
参考:独自 error_messages_for の作成

redMine

プロジェクト管理ソフトウェアだそうです。ソースを見せてもらって勉強させてもらおう Ruby on Railsで作られたプロジェクト管理ツールredMineを使ってみよう

リンク

api
Rails API ドキュメント
ActiveRecord
RubyOnRails を使ってみる
Rubyでアジャイルプロトタイピング
ajax_scaffold_generator
Ruby Library Report 【第 3 回】 O/R マッピング
RubyOnRails を使ってみる 【第 8 回】 Rails はまり道 出退勤のサンプルを題材としておられます。
pagination
AvailableGenerators
メーリングリスト
RailsでWikiクローンを作る
WebプログラマはRailsに乗るべきか?
Ruby on Rails on MacOSXでWebアプリ開発
Rails Plugins...
Ruby on Railsのチームから学ぶ仕事術
境界を越える: アクティブ・レコードを探る
Java開発者のためのRubyガイド
Ruby on Rails 初心者の館 Aptana + InstantRails?を使った環境の構築をWinkをつかってわかりやすく説明してあります。
Ruby on Rails チュートリアル集
10分で作るWikiがあります。実際は12分らしいですが、たいしたもんだ。
Ruby on Rails 2.0にアップグレードする方法
Ruby on Rails チュートリアル 「Webアプリケーション開発方法」
Visual Studioを使ってRails開発「Ruby In Steel Personal Edition 2008」
Visual Studioは使わないのですが、一応
RJSなら数行のRubyコードでAjaxアプリを作成できる
Railsでレガシーデータを蘇えらせるテクニック
どこでもできるRails開発「Ruby on Rails Portable」
Rails製のシンプルなEコマースシステム「EcomPages」
Rails 2.2 について興味が湧いたところだけ見てみました
created_at、updated_atの実装コードを追ってalias_method_chainを理解する
Rails 2.1・その12(DBに登録してあるUTC日付データを簡単変換)

参考書籍

RailsによるアジャイルWebアプリケーション開発
Railsをやるのであればとりあえず買っておきたい本です。

コメント

  • #comment

トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-09-30 (水) 00:11:00 (5337d)