chankoその2:使い方
前回の続き。
これから、実際にプロトタイプを作成する。
前提)
- chankoのinstallまで終わっている
- 既にある程度作成したrails3.xのアプリがある
目次
- generatorを使って、ソースの元を作成
- prototypeを使うUserを決める
- controllerに追加する
- viewに追加する
- modelに追加する
1)generatorを使って、ソースの元を作成
以前書いた通り、以下のコマンドで作成する。
be
g chanko sample
create app/units/sample/sample.rb
create app/units/sample/views/_show.html.erb
create app/units/sample/spec/controllers/sample_controller_spec.rb
create app/units/sample/spec/models/sample_model_spec.rb
create app/units/sample/spec/helpers/sample_helper_spec.rb
create app/units/sample/stylesheets/sample.scss
create app/assets/stylesheets/units/sample
create app/units/sample/javascripts/sample.js
create app/assets/javascripts/units/sample
create app/units/sample/images/logo.png
create app/assets/images/units/sample
この際に、名前(上記で言う、sampleの事)は、機能名を入れるらしい。
http://techlife.cookpad.com/2011/07/15/extension-framework/
機能単位で切って管理するらしい。
2)prototypeを使うUserを決める
例えば、ApplicationController.rbに既に、
ログイン済のUserを取得するmeメソッドが存在しており、
そのuser idが1番目の人のみにprototypeを適用する場合。
# lib/chanko/active_if/active_if.rb
Chanko::ActiveIf.define(:specified_user) do |context, options|
context.me.id == 1
end
# app/units/sample/sample.rb
active_if :specified_user
このactive_ifというのが、trueの場合にのみ、prototype環境になる様子。
この条件は、以下のどちらに書いても良い
- lib/chanko/active_if(おそらく、基本はここ)
- app/units/sample/sample.rb(機能単位で個別に、特定のuserを指定したい場合こちら。)
また、ブロックパラメータのcontextには、controller等が入ってくるらしい。
※詳細は後述
3)controllerに追加する
ここでは、例として既に存在するrailsアプリのアクション内で
logへの標準出力を表示する際に、
- 通常時、normalと表示して
- プロトタイプ時、prototypeと表示する
# app/controllers/application_controller.rb
invoke(:sample, :show) do
puts 'normal##############' # 通常時、こちらを表示
end
# app/units/sample/sample.rb
scope(:controller) do
function(:show) do
puts 'prototype##################' # prototype時、こちらを表示
end
end
scopeに、どこ(controllerか?viewか?)に対して追記するのか?書く。
functionが、追加する関数。
4)viewに追加する
今回は、railsアプリのapplication.html.erbに、
- 通常時は、it is normal
- prototype時は、it is prototype
と表示を切り分けるようなものを作る
# app/views/layouts/application.html.erb
<%= invoke(:sample, :show) do %>
it is normal # もし、active_ifがfalseの場合、こちらを表示する
<% end %>
# app/units/sample/sample.rb
scope(:view) do
function(:show) do
render :partial => "/show" #(prototype時、ここで指定した以下のファイルを表示)
end
end
# app/units/sample/views/_show.html.erb
it is prototype
5) modelに追加する
ここでは、既にPostモデルが存在していて、
複数の情報を返すindexメソッドが既に存在するとして、
そのメソッドをprototype時のみ、最後の1件のみ返すメソッドに変える。
# app/units/sample/sample.rb
models do
expand("Post") do
class_methods do
def index
[self.last]
end
end
end
end
# app/controllers/posts_controller
if ext(:sample).active? # sampleのactive_ifがtrueになっている(prototype見せている)
@posts = Post.ext(:sample).home #特別に用意されたmethodを実行
else
@posts = Post.home
end
railsアプリのmodel側は特にinvokeする必要はない見たい。
ちなみに、chankoのwikiやコメントには、
Model.ext.methodで実行できるとあるが、そう書くと以下のエラーになる。
Chanko::NoExtError (Chanko::NoExtError):
実際は、Model.ext(chankoで作った機能名:ここで言うsample).methodと書くのが正しいようで、
そう書くと、上記エラーがでなくなる。
※まあ、複数あれば、どのunits使うか特定できないしね。
使ってみて気になった所
#context
-controller
呼び出しているcontrollerそのものっぽい。
なので、例えば、applicationcontrollerのprivate method等あるのであれば、
send経由でないと呼べないので、注意。
-view
(※おそらく)viewを実行しているApplicationControllerのインスタンス?
-model
???多分、viewと同じ?これは、まだ、ちゃんと見てない。
# ソース修正
例えば、lib/chanko/active_ifをいじると、
local環境でも、server起動しなおさないと、適用されないので、注意。
※多分、staticに扱われていて、server起動時にメモリに入っているのでしょうね。