Ruby on Rails Tutorial (26)
ということで掘削対応に着手。とりあえず rake routes 確認。
$ rake routes following_user GET /users/:id/following(.:format) users#following followers_user GET /users/:id/followers(.:format) users#followers users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy sessions POST /sessions(.:format) sessions#create new_session GET /sessions/new(.:format) sessions#new session DELETE /sessions/:id(.:format) sessions#destroy microposts POST /microposts(.:format) microposts#create micropost DELETE /microposts/:id(.:format) microposts#destroy relationships POST /relationships(.:format) relationships#create relationship DELETE /relationships/:id(.:format) relationships#destroy root / static_pages#home signup /signup(.:format) users#new signin /signin(.:format) sessions#new signout DELETE /signout(.:format) sessions#destroy help /help(.:format) static_pages#help about /about(.:format) static_pages#about contact /contact(.:format) static_pages#contact
redmine は横幅がパなかったですが、こちらはまだ規模的にもアレ。
ふと思いついたのですが、これって mindmap でプレゼンテーションできんかな。http://mind42.com/ にアカウントがあったはず、ということで作成着手。
root : static_pages#home から遷移可能なのは以下か。
- help : static_pages#help
- about : static_pages#about
- contact : static_pages#contact
- signup : users#new
ええと、これって header とか footer とかもアレですね。
- signin : sessions#new
- signout : sessions#destroy
- users : users#index
- edit_user : users#edit
- user : users#show
む、あと以下もか。
- micropost : microposts#create
あるいは following とか follower とかか。
- following_user : users#following
- followers_user : users#followers
なんかほとんど全部じゃんかorz
むむ、よくよく見たら自分のポストは削除可能だな。
- micropost : microposts#destroy
このあたりで mindmap に反映させといて
- static_pages
- users
- microposts
- follow
なあたりの順で掘削してみるか。とりあえず現時点の mindmap も貼っておきます。
とりあえずここで一旦エントリ投入しといて掘削云々は追記の方向。
とりあえず static_pages な controller から
以下な定義。非常に簡単ですね。
class StaticPagesController < ApplicationController def home if signed_in? @micropost = current_user.microposts.build @feed_items = current_user.feed.paginate(page: params[:page]) end end def help end def about end def contact end end
始点なので app/views/layout 配下のソレも確認が必要なのか。ちなみに controller ですが root なアクションにて signed_in? であれば view で使われている変数に諸々の設定を行なっていらっしゃいますね。最初なので一つひとつ丁寧に掘ってみます。
- signed_in? メソドについて
- current_user について
- User#microposts および build ってメソドについて
- User#feed とか pagenate とか
上記確認後に app/views/layout 配下を云々。
signed_in? メソドについて
signed_in? は app/helpers/sessions_helper.rb にて定義されてます。app/helpers 配下って application_helper.rb と controller 作ったときに自動で作成されるヤツが、なんですかね。同じ名前のヤツがありますが。
でも今見てるのって static_pages_controller.rb だな。むむむ。
で、app/controllers/application_controller.rb 見てみたら以下な定義でした。
class ApplicationController < ActionController::Base protect_from_forgery include SessionsHelper end
これで SessionHelper で定義されている属性はアプリケーショングローバルになるのか。つうかこれってどこで設定したんだろ。
git log app/controllers/application_controller.rb
で、以下な出力。今回のリポジトリはこれ系の探索が無意味だったりしますがorz
commit 52535ebf8cbb97bb0cae57d2f6c2147719b85f35 Author: YAMANE Toshiaki <yamanetoshi@gmail.com> Date: Fri Jan 25 19:55:23 2013 +0900 Chapter 8 Sign in, sign out commit d702fa72199dc441511c7ec08e528fd0db906708 Author: YAMANE Toshiaki <yamanetoshi@gmail.com> Date: Wed Jan 16 08:35:14 2013 +0900 initial commit
む、Chapter 8 ですな。8.2.1 にて修正を盛り込んでおります。いやはや。しかし git は良い道具ですな。今回は使い方間違えちゃってるけどorz
app/helpers 配下については
- application.rb はシステムグローバル
-helper.rb はその controller でのみ有効 - 今回は app/controllers/application_controllers.rb で include されたのでシステムグローバルで sessions_helper.rb なソレ達が可視範囲になった
という理解で良いのかどうか
current_user について
signed_in? メソドは以下な定義になってて
def signed_in? !current_user.nil? end
ここでも出てくる current_user というソレについても確認。
あ、current_user は SessionHelper の属性なんスね。イマサラですが使いかた的に面白くて以下が sign_in の定義。
def sign_in(user) cookies.permanent[:remember_token] = user.remember_token self.current_user = user end
remember_token の詳細はここではスルーしますが、session cookie てきなソレを設定して current_user な属性に引数な User オブジェクトをセットしてます。
あるいは current_user な属性への setter が以下。
def current_user=(user) @current_user = user end
これはそのまんまですね。その下に getter がありますがこれも面白い。
def current_user @current_user ||= User.find_by_remember_token(cookies[:remember_token]) end
サーバ側で session cookie が残ってたらそれを使おうとなさってらっしゃいます。つうか cookies てのは何かな。別途確認。
User#microposts および build ってメソドについて
app/models/user.rb で以下な記述があります。
has_many :microposts, dependent: :destroy
関連する Micropost なオブジェクトを配列で保持してる形。あら、build て何でしょ。
@micropost = current_user.microposts.build
ええと http://railsdoc.com/model には以下な記述がありますね。
新しいモデルを作り、多対多で関連付けるがDBは更新しない
おそらく一対多の typo だと思いますがこの micropost なオブジェクトは入力フォームのためにあるようですね。app/views/shared/_micropost_form.html.erb のソレ。
とりあえずこの程度でスルーします。
User#feed とか pagenate とか
以下な記述のソレ。
@feed_items = current_user.feed.paginate(page: params[:page])
app/models/user.rb 見てみるに以下な記述がありますね。
def feed Micropost.from_users_followed_by(self) end
app/models/micropost.rb の定義が以下。
def self.from_users_followed_by(user) followed_user_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id" where("user_id IN (#{followed_user_ids}) OR user_id = :user_id", user_id: user.id) end
む、ここってかなりスルーしてるんだけど。よくよく見てみるとアレですね。つうかサブクエリなのか。たしか followed_user_ids に id な配列だかコンマ区切りの文字列だかを云々する場合件数が莫大だとアレじゃないですかね? 的問題に対応したものだったはず。なんとなくこのあたりも後天性記憶不全がorz
paginate も確認しておきます。
以下な gem が導入されております。
$ grep pag Gemfile gem 'will_paginate', '3.0.3' gem 'bootstrap-will_paginate', '0.0.6'
おそらく今ってこれがデフォなんだろうな。以下が git なリポジトリらしい。
app 配下を grep してみたら app/views 配下でも使われてますね。
$ find app/|xargs grep paginate ./app/views/users/show.html.erb: <%= will_paginate @microposts %> ./app/views/users/show_follow.html.erb: <%= will_paginate %> ./app/views/users/index.html.erb:<%= will_paginate %> ./app/views/users/index.html.erb:<%= will_paginate %> ./app/views/shared/_feed.html.erb: <%= will_paginate @feed_items %> ./app/controllers/static_pages_controller.rb: @feed_items = current_user.feed.paginate(page: params[:page]) ./app/controllers/users_controller.rb: @microposts = @user.microposts.paginate(page: params[:page]) ./app/controllers/users_controller.rb: @users = User.paginate(page: params[:page]) ./app/controllers/users_controller.rb: @users = @user.followed_users.paginate(page: params[:page]) ./app/controllers/users_controller.rb: @users = @user.followers.paginate(page: params[:page])
ちなみに app/views/users/index.html.erb ですが、最終版が以下。
<% provide(:title, 'All users') %> <h1>All users</h1> <%= will_paginate %> <ul class="users"> <%= render @users %> </ul> <%= will_paginate %>
なんだか凄いことになってます。これ、9.3 あたりで云々されている模様。最初はこんなカンジだったのですが
<% provide(:title, 'All users') %> <h1>All users</h1> <ul class="users"> <% @users.each do |user| %> <li> <%= gravatar_for user, size: 52 %> <%= link_to user.name, user %> </li> <% end %> </ul>
9.3.3 で will_paginate が導入されたのか。全然記憶に無い。
gem 'will_paginate', '3.0.3' gem 'bootstrap-will_paginate', '0.0.6'
Listing 9.34 で以下になっています。
<% provide(:title, 'All users') %> <h1>All users</h1> <%= will_paginate %> <ul class="users"> <% @users.each do |user| %> <li> <%= gravatar_for user, size: 52 %> <%= link_to user.name, user %> </li> <% end %> </ul> <%= will_paginate %>
成程。view で使うとここからここまで pagination してね、って意味になるのかな。とは言え、app/views/users/show_html.erb だと以下な記述があったりとか
<% if @user.microposts.any? %> <h3>Microposts (<%= @user.microposts.count %>)</h3> <ol class="microposts"> <%= render @microposts %> </ol> <%= will_paginate @microposts %> <% end %>
あるいは app/views/users/show_follow.html.erb で以下な記述があったりとか
<% if @users.any? %> <ul class="users"> <%= render @users %> </ul> <%= will_paginate %> <% end %>
ここでの使われかた、はどうなのか。あるいは先の類推はダウトなのかビンゴなのか。
cookies について
デフォで用意されちゃってる模様。
app 配下 grep したら以下なカンジ。
$ find app |xargs grep cookies app/helpers/sessions_helper.rb: cookies.permanent[:remember_token] = user.remember_token app/helpers/sessions_helper.rb: @current_user ||= User.find_by_remember_token(cookies[:remember_token]) app/helpers/sessions_helper.rb: cookies.delete(:remember_token) app/helpers/sessions_helper.rb~: cookies.permanent[:remember_token] = user.remember_token app/helpers/sessions_helper.rb~: @current_user ||= User.find_by_remember_token(cookies[:remember_token]) app/helpers/sessions_helper.rb~: cookies.delete(:remember_token)
とりあえず
一旦手を置いてばんめし製造に着手します。とりあえず残りとして
- will_paginate の view での使われかた
- app/views/layout 配下を云々
が継続。