2012年3月3日土曜日

初めてのrails


このエントリーをはてなブックマークに追加


【第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 件のコメント:

コメントを投稿