【第2回】yoyogi.rb Ruby初心者向け で、HatchUp!に行ってきました。
教材
commitsログが教材
nysalor/twit
railsインストール
sudo gem install rails
Building native extensions. This could take a while...
ERROR: Error installing rails:
ERROR: Failed to build gem native extension.
/usr/bin/ruby1.9.1 extconf.rb
<internal:lib/rubygems/custom_require>:29:in `require': no such file to load -- mkmf (LoadError)
from <internal:lib/rubygems/custom_require>:29:in `require'
from extconf.rb:1:in `<main>'
Gem files will remain installed in /var/lib/gems/1.9.1/gems/json-1.6.5 for inspection.
Results logged to /var/lib/gems/1.9.1/gems/json-1.6.5/ext/json/ext/parser/gem_make.out
失敗。mkmfがない。
apt-cache search mkmf
apt-get install ruby1.9.1-dev
sudo gem install rails
プロジェクト作成
rails new twit -T #TはTest::Unitを入れない
複数バージョンのruby,rails管理
rvm(Ruby Version Manager )
http://www.machu.jp/diary/20110521.html#p01
perlbrewみたいなもの?今回はスルー。
サーバー起動
rails server
エラー。
javascriptの新しいエンジンがいるようだ。
node.jsをいれてもいいけど、
projectディレクトリ内のGemfileを編集。
# 追記
gem 'execjs'
gem 'therubyracer'
bundle install
これでサーバーが起動できる。
ひな型作成
userモデルとuserコントローラ作成
viewもあるけど、scaffoldだから?雛形をいじるのはどこ?
rails g scaffold User name:string
Tweetモデル作成
rails g model Tweet body:string user_id:integer
以下が作成される。timestampsは勝手に作成されるのね。
# twit/db/migrate/....._create_tweets.rb
class CreateTweets < ActiveRecord::Migration
def change
create_table :tweets do |t|
t.string :body
t.integer :user_id
t.timestamps
end
end
end
# app/models/tweet.rb
class Tweet < ActiveRecord::Base
end
作成したモデルから、テーブル作成。(db/schema.rbが設定される)
rake db:migrate
テーブル間のリレーションを定義
belongs_to
tweetがuserに属していることを記述。一方通行の関係性ですね。
これ、tweetテーブルにuser_idってカラムを自分で作成しないでいいんですね。
# app/models/tweet.rb
class Tweet < ActiveRecord::Base
belongs_to :user
end
# app/models/user.rb
class User < ActiveRecord::Base
has_many :tweets
end
users#showにtweetを表示
<p>
<b><%= @user.name %>さんのつぶやき</b>
<ul>
<% @tweets.each do |tweet| -%>
<li><%= tweet.body %></li>
<% end -%>
</ul>
</p>
tweetを表示させる。
コントローラに書いてある@hogeはインスタンス変数なので、viewで使用できると言われてよくわからなかったけど、
<% %>はruby文法をそのまま記述しているからっぽい。
userコントローラにtweetメソッド追加
# POST /users/1/tweet
def tweet
@user = User.find(params[:id])
@tweet = @user.tweets.create(:body => params[:body])
redirect_to @user, notice: 'Tweet was successfully updated.'
end
tweetメソッドに与えるパラメータをurlから取得
# config/routes.rb
match '/user/:id/tweet' => 'users#tweet', :as => :user_tweet
/user/1/tweet にアクセスすると、usersコントローラのtweetメソッドの :idに1が入る。
:asでメソッドへのalias設定。'_path'を末尾に追加した名前が使える。
# views/users/show.html.erb
<%= form_tag user_tweet_path do %>
今何してる?:<%= text_field_tag :body %>
<%= submit_tag %>
<% end -%>
ロジックをコントローラからモデルに移動
@user.tweets.create(:body => params[:body]);をUserモデルのメソッドに。
メソッド名はtweet!のようにビックリをつけるのが好みだそう。
orderメソッド
@user.tweets.order('created_at DESC')
で日付順を逆に。
orderって記述はActiveRecordeのメソッド?
scopeでsqlの遅延評価
直接sqlを書かないようにするだけならメソッド化でいいが、遅延評価できるようにscopeを使用。
モデルクラスに、
scope :newer, order('created_at DESC')
と書いてnewerメソッドとして使用。
@user.tweets.newer.limit(10) としても、全件とってきてから10件取得しないで済む。
partial(部分テンプレート)
TTでいうところの、INCLUDE,PROCESSみたい。外部ファイル読み込み。
<%= render :partial => "tweets" %>
_tweets.html.erbって名前のファイル内容を挿入してくれるっぽい。
命名規則があるのかな?だとするとちょっと分かりにくいかなぁ。
TTみたいにパスを直接書くほうが管理しやすいかも。
メモ
:collection で渡しているインスタンス名がパーシャルの名前とそろっていること。規約により、hogehoge.html.erbをコレクションのサイズだけループしてくれるらしい。そしてさらに引数が渡したければ、localsを使う。
ajax
まず、ajaxだからredirect_toは削除。
form_for、link_to:remote => trueを加えると非同期処理になる。
サンプルではajaxでテンプレートを貼り付けてたけど、テンプレートが評価された後にJSの引数として評価されてるのかな。
0 件のコメント:
コメントを投稿