Getting Started With Rails
本家のGetting Startedってのを真似て進めてみました。
以下はその際のメモ書きです。
- Getting Started With Rails
DB作成
database.yml編集。
development: adapter: mysql encoding: utf8 database: blog_development pool: 5 username: root password: socket: /var/lib/mysql/mysql.sock
実行。
rake db:create
generate
script/generate controller home index
デフォルトルートの変更
config/route.rbに以下行を追加。
map.root :controller => "home"
これでHomeControllerのindexアクションがデフォルトになる。
Scaffolding
scaffoldingが出てきた。
>script/generate scaffold Post name:string title:string content:text exists app/models/ exists app/controllers/ exists app/helpers/ create app/views/posts exists app/views/layouts/ exists test/functional/ exists test/unit/ exists public/stylesheets/ create app/views/posts/index.html.erb create app/views/posts/show.html.erb create app/views/posts/new.html.erb create app/views/posts/edit.html.erb create app/views/layouts/posts.html.erb create public/stylesheets/scaffold.css create app/controllers/posts_controller.rb create test/functional/posts_controller_test.rb create app/helpers/posts_helper.rb route map.resources :posts dependency model exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/post.rb create test/unit/post_test.rb create test/fixtures/posts.yml create db/migrate create db/migrate/20090115171317_create_posts.rb
特に追加インストールなどせずに使えている?
とりあえず先に進む。
>rake db:migrate (in /home/qnzm/tmp/blog) == CreatePosts: migrating ==================================================== -- create_table(:posts) -> 0.0074s == CreatePosts: migrated (0.0140s) ===========================================
db/migrate配下にpostsテーブル作成用のクラスが作成されていてそれが適用された。
class CreatePosts < ActiveRecord::Migration def self.up create_table :posts do |t| t.string :name t.string :title t.text :content t.timestamps end end def self.down drop_table :posts end end
引数指定したフィールドがデフォルトで設定されているのかな。
Postモデルに検証を追加
class Post < ActiveRecord::Base validates_presence_of :name, :title validates_length_of :title, :minimum => 5 end
readline
script/consoleの実行にはreadlineのインストールが必要でした。
sudo yum install readline-devel sudo ruby extconf.rb make sudo make install
script/console
コンソールからモデルクラス作っていじって反応みたり、できるらしい。
>script/console Loading development environment (Rails 2.2.2) >> p = Post.create(:content => "A new post") => #<Post id: nil, name: nil, title: nil, content: "A new post", created_at: nil, updated_at: nil> >> p.save => false >> p.errors => #<ActiveRecord::Errors:0xb7d97bd4 @errors={"name"=>["can't be blank"], "title"=>["can't be blank", "is too short (minimum is 5\ characters)"]}, @base=#<Post id: nil, name: nil, title: nil, content: "A new post", created_at: nil, updated_at: nil>> >>
パーシャル
「新規作成」と「編集」で重複してしまうフォームの形式をパーシャルなテンプレートとして別にしておき、render指定で取り込むことができる。
_form.html.erbとして、
<% form_for(@post) do |f| %> <%= f.error_messages %> <p> <%= f.label :name %><br /> <%= f.text_field :name %> </p> <p> <%= f.label :title, "title" %><br /> <%= f.text_field :title %> </p> <p> <%= f.label :content %><br /> <%= f.text_area :content %> </p> <p> <%= f.submit "Save" %> </p> <% end %>
を作っておいて、
<h1>Editing post</h1> <%= render :partial => "form" %> <%= link_to 'Show', @post %> | <%= link_to 'Back', posts_path %>
Commentモデルの導入
script/generate model Comment commenter:string body:text post:references
このmodelの指定は分かりやすい。同時に項目の構成も指定しているわけか。
>rake db:migrate (in /home/qnzm/tmp/blog) == CreateComments: migrating ================================================= -- create_table(:comments) -> 0.0465s == CreateComments: migrated (0.0576s) ========================================
commentsテーブルができました。
ルーティングやDDL文なんかもRubyソースコードで表現されていて、Rubyの世界で開発しきるという感じ。
Adding a Route
map.resources :posts do |post| post.resources :comments end
Commentページの作成
@commentsと@commentを間違えたりしてエラー吐いた。それらを調整して動くように仕向けていく中、結果として全体の振る舞いを見ていっていた気持ち。
comment_controller.rb内。
def new @post = Post.find(params[:post_id]) @comment = @post.comments.build end
buildで新しいCommentオブジェクトは作られるけど、このタイミングではまだデータベースに保存されていない、新たなオブジェクトができただけ、とか。
class Comment < ActiveRecord::Base belongs_to :post end
class Post < ActiveRecord::Base has_many :comments end
で関連を表していたり、とか。(最初、Postクラスに上記一行抜けていたため、「commentsフィールドなんて知りません」とエラーが出てた)
link_toに指定する"post_comment_path"
<td><%= link_to 'Show', post_comment_path(@post, comment) %></td> <td><%= link_to 'Edit', edit_post_comment_path(@post, comment) %></td>
viewのところどころで指定した"post_comment_path"といったアクション。
これがどう展開されるのかというと、どうも
map.resources :posts do |post| post.resources :comments end
を指定した段階で、コントローラアクションにindex/create/show/update/destroy/new/editを使用することになっていて、それらに対応するアクションメソッドが自動的に利用可能になるみたい。
- Rails Routing from the Outside In
post_comment_pathはshowアクションに関連付いて、edit_post_comment_pathはその名の通りeditアクションに関連付く。
commentはpostに対する従属モデルだから、名前もネストした形で表現されている。routes.rbの表現もそれを表している。
引数がある/ない、単数形/複数形のアクション等等…ちょっと自分の頭でまだ整理できていない感じ。すとんと落ちてない。