前回の記事はこちら
ブログHeroku移転計画 その1 - 「Getting Started with Rails」をやってみた(1)「
Getting Started with Rails」の「5 Getting Up and Running Quickly with Scaffolding」から再開。
■5~6.scaffoldを作ったり、リソースを作ったり。
次はscaffoldか。
さて、本家はどこまで作ってくれるんだろう。
rails generate scaffold Post name:string title:string content:text
invoke active_record
create db/migrate/20110424014627_create_posts.rb
create app/models/post.rb
invoke test_unit
create test/unit/post_test.rb
create test/fixtures/posts.yml
route resources :posts
invoke scaffold_controller
create app/controllers/posts_controller.rb
invoke erb
create app/views/posts
create app/views/posts/index.html.erb
create app/views/posts/edit.html.erb
create app/views/posts/show.html.erb
create app/views/posts/new.html.erb
create app/views/posts/_form.html.erb
invoke test_unit
create test/functional/posts_controller_test.rb
invoke helper
create app/helpers/posts_helper.rb
invoke test_unit
create test/unit/helpers/posts_helper_test.rb
invoke stylesheets
create public/stylesheets/scaffold.css
お、全部出来てるわw
凄いな、コントローラ、モデル、ビュー、テストまで一式だ。
次にデータベースの更新。
rake db:migrate
migrationってのがよくわかんないんだけど、すげ=便利そう。
CakePHPはこの辺弱かったし、似たようなことは出来るんだけど、そこまでみんな使ってない気がするな。
けどまあ、奥が深そうだ。
次、モデルのバリデーションか。
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true, :length => { :minimum => 5 }
end
見た目で大体何やっているのかわかるのがすごいな。
presenceは未入力かどうかのチェックらしい。
なんかコンソールを使うとか書かれているので、そのまま入力。
$ rails console
んで、言われるがままに入力すると、同じ内容が帰ってきた。
>> p = Post.new(:content => "A new post")
=> # content: "A new post", created_at_at: nil,
updated_at: nil>
>> p.save
=> false
>> p.errors
=> #["can't be blank",
"is too short (minimum is 5 characters)"],
:name=>["can't be blank"] }>
これすげー!
コンソール上でRails上のクラスとかメソッドが呼べるのかあ。
なんかいろいろ使えそうなんだけど、いまいち使い方が思いつかない・・・。
お、次はいよいよデータベースの内容を表示する一連の流れかな。
コントローラの中身を確認してみると、いろいろ出来てる。
んで、Viewもおんなじ様にいろいろ出来ている。
んで、レイアウトを変更するとな?
@/app/views/layouts/application.html.erb
-
+
色つけただけ。
ブラウザで確認すると、確かに変わっている。
Railsだとデフォルトのレイアウトはapplication.html.erbって名前なのか。
んで、
記事の投稿、編集、削除、参照という一連のCRUDの流れの説明。
Viewファイル的には殆ど変わらない投稿と編集ページが、どうやってFormのアクション先を振り分けているかは良くわからなかった。
けど、Railsがうまく隠蔽してくれているといえばそうなのか。
これはちょっとでもルールから外れるとすげー面倒くさそうかも。
んで、ざーっと読み飛ばしてw「7 Adding a Second Model」へ
コメントのモデルを作るってことね。
■7.2個目のモデルを作る
$ rails generate model Comment commenter:string body:text post:references
$ rake db:migrate
post:referenceって書くだけで参照してくれるのか。
そういえばテーブルも作りもCakePHPとほぼ一緒だな。
postsモデルにも関連付けを追加。
has_manyだと。
@/app/models/post.rb
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true, :length => { :minimum => 5 }
+ has_many :comments
end
次にroutes.rbに以下の項目を追加するらしいんだけど、これが全くさっぱりわからん。
後から分かってくるかな?
@/configroutes.rb
- resources :posts
+ resources :posts do
+ resources :comments
+ end
迷わず行けよ、行けばわかるさ。
コメントコントローラの生成ね。
$ rails generate controller Comments
んでポストのshowビューに以下の様に変更。
コメントを投稿できるようにするっぽい。
@/app/views/posts/show.html.erb
<%= notice %>
Name:
<%= @post.name %>
Title:
<%= @post.title %>
Content:
<%= @post.content %>
Add a comment:
<%= form_for([@post, @post.comments.build]) do |f| %>
<%= f.label :commenter %>
<%= f.text_field :commenter %>
<%= f.label :body %>
<%= f.text_area :body %>
<%= f.submit %>
<% end %>
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %> |
この中で
<%= form_for([@post, @post.comments.build]) do |f| %>
がよくわかんないけど、これでよろしくやってくれているんだろう。
んで、コメントコントローラーにもメソッド追加
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(params[:comment])
redirect_to post_path(@post)
end
createメソッドがpostコントローラから始まっているところがみそっぽいな。
実際にフォームから送信しようとすると
/posts/2/comments
みたいなURLになっているので、大したものだなあ。
この辺はちょっとどこかで解説みないとわかんないな。
んで、再度showビューを編集して、コメントの一覧が見えるようにする。
+ Comments
+ <% @post.comments.each do |comment| %>
+
+ Commenter:
+ <%= comment.commenter %>
+
+
+
+ Comment:
+ <%= comment.body %>
+
+ <% end %>
なんだかよくわからないことが増えてきた。
先ほどroutes.rbに追加したのは、どうやら
/posts/1/comments/1
みたいなルーティングを実現したい時に使うっぽい。
あとフォーム周りはようわからんな。
これ実際に自分でつくろうとすると、必ず躓くな。
が、ひとまず前に進もう。
■8.リファクタリング
次はリファクタリング。
まさかのリファクタリング指南コーナーか。
まずはパーツ作り。
@/app/views/comments/_comment
Commenter:
<%= comment.commenter %>
Comment:
<%= comment.body %>
@/app/views/comments/_form.html.erb
<%= form_for([@post, @post.comments.build]) do |f| %>
<%= f.label :commenter %>
<%= f.text_field :commenter %>
<%= f.label :body %>
<%= f.text_area :body %>
<%= f.submit %>
<% end
次に読み込む先をごにょる。
@/app/views/posts/show.html.erb
<%= notice %>
Name:
<%= @post.name %>
Title:
<%= @post.title %>
Content:
<%= @post.content %>
Comments
<%= render :partial => "comments/comment",
:collection => @post.comments %>
Add a comment:
<%= render "comments/form" %>
<%= link_to 'Edit Post', edit_post_path(@post) %> |
<%= link_to 'Back to Posts', posts_path %>
ポイントは
<%= render :partial => "comments/comment",
:collection => @post.comments %>
<%= render "comments/form" %>
の2箇所。
やっていることは大体わかる。
ただ、collectionって指定すると、中でループを展開してくれるっぽい。
あとは、form_forメソッドで、指定しているのは、関連付けされているモデルの場合の指定方法みたいだ。
buildってメソッドもその一環らしい。
それぞれモデルクラス、formヘルパークラスの説明部分にそれっぽいことが書いてあった。
けど、英語か・・・。
細かい部分は自信ないな。
けど、この辺のヘルパーやモデルの関係もCakePHPと似ている。
より強力な感じだけども。
■9.コメントの削除
次は削除処理か。
@/app/views/comments/_comment.html.erb
+
+ <%= link_to 'Destroy Comment', [comment.post, comment],
+ :confirm => 'Are you sure?',
+ :method => :delete %>
+
link_toはURLヘルパーかな?
もはや何ヘルパーに属しているかさえも分からんくなっているな。
comment.postでそれぞれ:comment.post_idや:idをどうやら指定しているのかな?
んー。
ちと分かりづらいな。
次のコントローラ部分へのメソッドの追加をみるとそんな感じなんだけど。
@/app/controllers/comments_controller.rb
+ def destroy
+ @post = Post.find(params[:post_id])
+ @comment = @post.comments.find(params[:id])
+ @comment.destroy
+ redirect_to post_path(@post)
+ end
んで、記事が消されたらコメントも消そうというのが以下の設定。
ふむふむ。
@/app/models/post.rb
class Post < ActiveRecord::Base
validates :name, :presence => true
validates :title, :presence => true, :length => { :minimum => 5 }
+ has_many :comments, :dependent => :destroy
end
dependentってのは分かりやすいわ。
長くなったので今回もここまで。
続きます。
ブログHeroku移転計画 その3 - 「Getting Started with Rails」をやってみた(3)