読者です 読者をやめる 読者になる 読者になる

電車本4版でRails勉強し始めた頃のメモが見つかった。。

ruby rails

RailsによるアジャイルWebアプリケーション開発 第4版
RailsによるアジャイルWebアプリケーション開発 第4版

メモが手元に残っていたのでup。。あまりこの頃とレベル変わっていないな。。

Windows7でやっています。先輩はlinuxでやった方がいいと言ったけど横着しました。。仕事でもWindowsだし。。

ちなみに電車本自体はしばらく勉強して飽きちゃいました。。

Railsアプリ新規作成

railsのバージョンを確認

RailsInstaller実行後、

PS$gem list --local rails

###  LOCAL GEMS ***

rails (3.1.0)

4版の電車本なのでRails3です。

アプリケーションの作成

PS$rails new demo
      create
      create  README
      :
      :
      create  vendor/plugins/.gitkeep
         run  bundle install
Fetching source index for http://rubygems.org/
Installing rake (10.0.3)
:
:
Installing uglifier (1.3.0)
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
PS$cd .\demo
PS$ls


    ディレクトリ: xxxxxxxxxxxxxxxxxxxxxxxxxx


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2013/01/06     19:33            app
d----        2013/01/06     19:33            config
d----        2013/01/06     19:33            db
d----        2013/01/06     19:33            doc
d----        2013/01/06     19:33            lib
d----        2013/01/06     19:33            log
d----        2013/01/06     19:33            public
d----        2013/01/06     19:33            script
d----        2013/01/06     19:33            test
d----        2013/01/06     19:33            tmp
d----        2013/01/06     19:33            vendor
-a---        2013/01/06     19:33         49 .gitignore
-a---        2013/01/06     19:33        154 config.ru
-a---        2013/01/06     19:33        613 Gemfile
-a---        2013/01/06     19:34       2675 Gemfile.lock
-a---        2013/01/06     19:33        269 Rakefile
-a---        2013/01/06     19:33       9208 README

rake aboutでインストールの一般的なエラーも検出できる。

PS$rake about
About your application's environment
Ruby version              1.9.2 (i386-mingw32)
RubyGems version          1.7.2
Rack version              1.3
Rails version             3.1.0
JavaScript Runtime        JScript
Active Record version     3.1.0
Action Pack version       3.1.0
Active Resource version   3.1.0
Action Mailer version     3.1.0
Active Support version    3.1.0
Middleware                ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0
x2c26e60>, Rack::Runtime, Rack::MethodOverride, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::Rem
oteIp, Rack::Sendfile, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::Connection
Management, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Fla
sh, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsS
upport
Application root          xxxxxxxxxxxxxxxxxxxxxxx/demo
Environment               development
Database adapter          sqlite3
Database schema version   0

サーバ起動

PS$rails server
=> Booting WEBrick
=> Rails 3.1.0 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2013-01-06 20:57:02] INFO  WEBrick 1.3.1
[2013-01-06 20:57:02] INFO  ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2013-01-06 20:57:02] INFO  WEBrick::HTTPServer#start: pid=8736 port=3000


Started GET "/assets/rails.png" for 127.0.0.1 at 2013-01-06 20:59:10 +0900
Served asset /rails.png - 200 OK (8ms)

コントローラの作成

PS$rails generate controller Say hello goodbye
      create  app/controllers/say_controller.rb
       route  get "say/goodbye"
       route  get "say/hello"
      invoke  erb
      create    app/views/say
      create    app/views/say/hello.html.erb
      create    app/views/say/goodbye.html.erb
      invoke  test_unit
      create    test/functional/say_controller_test.rb
      invoke  helper
      create    app/helpers/say_helper.rb
      invoke    test_unit
      create      test/unit/helpers/say_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/say.js.coffee
      invoke    scss
      create      app/assets/stylesheets/say.css.scss

で、say_controller.rbにはhello()とgoodbye()がある。

scaffoldの作成

コントローラ以外にも諸々の“足場”を作ってくれるってことかな。

PS$rails generate scaffold Product `
>> title:string description:string image_url:string price:decimal
>>
      invoke  active_record
      create    db/migrate/20130121093012_create_products.rb
      create    app/models/product.rb
      invoke    test_unit
      create      test/unit/product_test.rb
      create      test/fixtures/products.yml
       route  resources :products
      invoke  scaffold_controller
      create    app/controllers/products_controller.rb
      invoke    erb
      create      app/views/products
      create      app/views/products/index.html.erb
      create      app/views/products/edit.html.erb
      create      app/views/products/show.html.erb
      create      app/views/products/new.html.erb
      create      app/views/products/_form.html.erb
      invoke    test_unit
      create      test/functional/products_controller_test.rb
      invoke    helper
      create      app/helpers/products_helper.rb
      invoke      test_unit
      create        test/unit/helpers/products_helper_test.rb
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/products.js.coffee
      invoke    scss
      create      app/assets/stylesheets/products.css.scss
      invoke  scss
   identical    app/assets/stylesheets/scaffolds.css.scss

このあとrake db:migrateでdb/migrate/xxxxxxxx_create_products.rbがマイグレーションされる。

rails generateでこさえた物はrails destroyで破棄できる様子

DB

DBをSQLite3以外にするならdatabase.ymlに別途手間が必要。
SQLite3だとしてもなんだかバージョンふるいと怒られることがある。
→Gemfileにgem 'turn', '< 0.8.3'

設定

config/database.yml

初期化?

seeds.rbを書いてからrake db:seed
初期化って言うのかインポートっていうのか。追々勉強か。。

マイグレーションをDBに適用

PS$rake db:migrate
==  CreateProducts: migrating =================================================
-- create_table(:products)
   -> 0.0010s
==  CreateProducts: migrated (0.0030s) ========================================

“逆向き”に適用すれば元に戻せるとかそんな感じ。

PS$rake --describe db:rollback
rake db:rollback
    Rolls the schema back to the previous version (specify steps w/ STEP=n).

PS$rake db:migrate:status

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20130121093012  Create products
   up     20130203190237  Create carts
   up     20130203194314  Create line items
   up     20130204140830  Add quantity to line items

このように4つのマイグレーションがあって、rake db:rollbackすると。。

PS$rake db:rollback
==  AddQuantityToLineItems: reverting =========================================
-- remove_column("line_items", :quantity)
   -> 0.1120s
==  AddQuantityToLineItems: reverted (0.1130s) ================================

PS$rake db:migrate:status

database: db/development.sqlite3

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20130121093012  Create products
   up     20130203190237  Create carts
   up     20130203194314  Create line items
  down    20130204140830  Add quantity to line items

という調子で1つずつマイグレーションが戻る。
まとめて戻したい場合はrake db:rollback step=4とか。

DBレイアウトを変更

rails generate migration add_xxxxxxxxx_to_tablename field:type
rails generate migration remove_xxxxxxxxx_from_tablename field:type

xxxxxxxはなんでもいい。

add_xxxxxxxxx_to_tablenameの部分が、railsが反応できない文字列だった場合、実装のない単純なup()/down()メソッドをもつ.rbファイルがdb/migrateに作られる。
rake db:migrateにup()が、rake db:rollbackにdown()が対応する。
データパッチも当てられる。

sqlite3の中身を覗く

sqlite3 -line .\db\development.sqlite3

モデル

バリデーション

基本はこんな調子らしく。。

class Product < ActiveRecord::Base
  validates :title, :description, :image_url, presence: true #有効な入力か
  validates :price, numericality: {greater_than_or_equal_to: 0.01} #指定値以上か
  validates :title, uniqueness: true #重複がないか
  validates :image_url, allow_blank: true, format: {
    with: %r{\.(gif|jpg|png)$}i,
      message: 'はGIF、JPG、PNG画像のURLでなければなりません'
    }
end

validetes()は中で単純にvalidates_xxxxxx_ofを呼んでいるだけらしい。

個別にエラーメッセージを指定する場合は

validates :title, length: {minimum: 10, message: 'は10文字以上入力してください'}
validates :image_url, allow_blank: true, format: {
  with: %r{\.(gif|jpg|png)$}i, message: 'はGIF、JPG、PNG画像のURLでなければなりません'
  }

という感じになる。それぞれおそらくvalidates_format_of(), validates_length_of()を読んでいるだけで、これらのメソッドに渡すパラメータがブロックで指定してある感じか。

ビュー

JavaScript

jQueryUIを使えるようにするにはapplication.jsにrequire jquery-uiを追記する。他のライブラリもここに書いてある様子。

CSS

app/assets/stylesheetsに置く。 そこのapplication.cssにrequire_treeとあると、そのディレクトリ内のスタイルシートはすべてapplication.cssに読みこまれるんだとか。

部分テンプレート

部分テンプレート名の変数で現在のオブジェクトにアクセスできる。
今のところモデル:ビューが1:1なもんだから部分テンプレートもモデルに紐付いているらしく、.html.erbに

<div>
  <%= render @cart %>
</div>

と書けばよい。(※ここ自分でも何思って書いたのか思い出せない)

ajaxリクエストはbutton_toヘルパーにremote: trueを渡すだけ。レスポンスは

respond_to do |format|
  if @line_item.save
    format.html { redirect_to store_url }
    format.js
    format.json { render json: @line_item, status: :created, location: @line_item }
  else
    format.html { render action: "new" }
    format.json { render json: @line_item.errors, status: :unprocessable_entity }

のformat.jsの部分を書き足して.js.erbを作成する。(詳しいことはまだ分からない)

ルーティング

config/routes.rb

  root to: 'store#index', as: 'store'

といった調子でルートを指定できる。コメントに書いてあるとおりpublic/index.htmlは消しておく。

unit test, functional test

rake test
rake test:functinal
rake test:units

なんかテスト結果の出力のされ方がおかしい。。

Windows7だからなのか何なのか。。
→なんだか色つけしようとして失敗した結果らしく、

PS$gem install win32console

で解決するといろんな所に書いてあるが解決しない。最新verの1.3.2から遡って1.3.0まで試したがダメだった。1.2.0はインストールできなかった。しにたい。

msys.batからならもしかして。。と思ったけどダメだった。
MinGWでWindowsソフト開発

※ひょっとしたらbundleしなかったからかもしれない。今となってはわからぬ。。

fixture

test/fixtureにYAMLファイルを置いておくとrailsがテストごとに勝手にロードしてくれるらしい。
するとfixureの名前のメソッドが勝手に作られるので、例えばproducts.ymlにoneという名前のデータがあったらproducts(:one)でオブジェクトがゲットできちゃうのだ。。

ロードするfixtureを明示したい場合は

class ProductTest < ActiveSupport::TestCase
  fixtures :products #test/fixtures/products.yml
  #...
end

rake db:test:prepareでもロードしてくれる。

文字列

'aaa\n'だとそのまま。
"bbb\n#{1+2}"だと\nがLFと解釈されるとか式が評価されるとかする。
%{bbb\n#{1+2}}はダブルクオートで囲うのと同じ。

電車本のサンプルコードにもダブルクオートをシングルクオートで書き間違えるとか普通にあるっぽい?

assets的な変更がなんか反映されない

PS$rake assets:clean

DevKitのtailでdevelopment.logを見るとマルチバイト文字が化ける

cat cat .\log\development.log -encoding utf8 | tail -f

ってやると化ける。

cat cat .\log\development.log -encoding utf8

だけだと化けない。
lessをUTF8版に差し替える必要あり?

参考:PowerShell - ねこ元帥の中の人

凡ミス

controller側で@productsと書いたつもりがつもりが\t@productsになっていて、.erbファイル側で「@products?そいつはnilだぜ!!!」って言われた。
タブ文字はとりあえず厳禁か。。