前提
- 超単純なモデル構造(1モデル)
- コントローラーはindex以外Ajax(シングルページな感じ)
- new, editなんかも新しいページに遷移するんじゃなくて、同じページ内にdivを挿入する感じ
- rails new済のところからスタート
- viewのhtmlレンダリングエンジンはhaml
前準備(Ajaxの前まで)
Model作成
$ ./bin/rails g model task name:string
Controller作成
$ ./bin/rails g controller tasks
RouteとControlle#index
ベースになるページを作る。
ルーティング設定
Rails.application.routes.draw do
root 'tasks#index'
resources :tasks
end
コントローラー
def index
@tasks = Task.all
end
ビュー(ベースになるページ)
%h1 Task List
%table{id: "tasks", class: "table"}
= render @tasks
補足
初心者的にようわからんポイントは、 = render @tasks
のとこ・・
これは省略されているだけで、フルで書くと
= render :partial => 'task', :collection => @tasks
になる。
参考:Rails Best Practices - Simplify render in views
ビュー(partial)
各taskをリスト表示する部分
%tr
%td=task.name
やっとこさAjaxしますよ!(こっから本題)
Step 1. 一覧ページに、TaskController#newのajax呼び出しをいれる
さっきのページに一番下に1行追加
ajaxなので remote: true
%h1 Task List
%table{id: "tasks", class: "table"}
= render @tasks
= link_to "New Task", new_task_path, remote: true
Step 2. Controllerの動き
def new
@tasks = Task.new
respond_to do |format|
format.html
format.js
end
end
scaffoldに従うと、こんな感じで、 respond_to
が入ってくる。
コレがないと対応したformatの呼び出しに応答してくれない。。
(htmlはデフォルトなのでなければhtml応答になる)
ここではrenderを省略しているので、Railsのデフォルトであるコントローラーアクション名と同名のテンプレートをレンダーしようとしてくれる。
remote: true なしの場合
HTMLを返そうとするので、探しに行くテンプレートは
app/views/tasks/new.html.haml
remote: true ありの場合
JSを探しに行く
app/views/tasks/new.js.erb
$('#task-form').html("<%= j (render 'form') %>");
$('#task-form').slideDown(350);
JSコードとして返され、評価される。
erbを使ってフォームのレンダリングを組み込んでいる。
ちなみにerbはRailsのデフォルトなのでhamlを使っていても使えないわけじゃない。
jsコード内にhamlは書きにくいらしいので、erbでやるほうがやりやすいらしい。
jsからレンダーされるform
= simple_form_for @task, remote: true do |f|
= f.input :description
= f.input :deadline
= f.button :submit
ここでも remote: true
が使われているが、これはsubmitのアクションをajax呼び出ししたいから。
ここでは新規作成後のPOSTなので、呼び出されるコントローラーは TasksController#create
def create
@task = Task.build(task_params)
respond_to do |format|
if @task.save
format.html
format.js
else
format.js { render :new }
end
end
end
呼び出されるのは format.js で指定されている app/views/tasks/create.js.erb
$('#tasks').html("<%= j (render @tasks) %>");
$('#task-form').slideUp(350);
j (render @tasks)
の j は ActionView::Helpers::JavaScriptHelper#escape_javascript
のエイリアスメソッド。
Escapes carriage returns and single and double quotes for JavaScript segments.
改行コード、シングルクオート、ダブルクオートをJavaScript用にエスケープしてくれるヘルパメソッド(のエイリアス)
erb が Ruby コードとして解釈した文字列をJavaScriptで正しく扱えるようにエスケープしてくれる。
この例の場合 render @tasks
なので、 app/views/tasks/_index.html.haml
が評価された文字列が入ってくる。
(RubyMineがあると、j
メソッドの呼び出しが何なのか、Cmd + B
で定義元にジャンプしてくれてとてもわかりやすい)
参考URL
めっちゃわかりやすいので、↑を見れば良い・・という・・・