Volt では、コントローラーがどのクラスであっても構いません。しかし、通常は Volt::ModelController
を継承したクラスとします。コントローラーはコンポーネント名の名前空間の中に配置されます。そのモデルコントローラーを使うことで、コントローラーによって利用されるモデルが明確になります。これは Volt で一般的に使われるパターンです。コントローラーが利用するモデルを設定するには以下のいずれかの方法を使います。
module Main
class TodosController < Volt::ModelController
model :page
# ...
end
end
self.model=
の呼び出し:module Main
class TodosController < Volt::ModelController
def initialize(*args)
# 必ず *args を設定し、super を呼び出してください
super
self.model = :page
end
end
end
モデルが設定されると、存在しないメソッドの呼び出しはすべてそのモデルに対してプロキシされます。これによって、ビューの中でバインディングを行う際に、毎回モデルのオブジェクトを指定しなくても済むようになっています。また、現在設定されているモデルから変更したときにビューが自動的に更新されるのも、この仕組みがあるためです。
ModelController 内で #model
を実行したときの戻り値は現在設定されているモデルとなります。
提供するコレクション の節に、利用可能なコレクションモデルのリストが記載されています。
また、自分で作成したオブジェクトをモデルとして提供することも可能です。
上記した例において、TodosController に定義されていないメソッドは、設定されているモデルにそのまま送られます。views/{コントローラー名}
フォルダのすべてのビューにおいて、そのバインディングの中にある Ruby コードを実行する対象はこのコントローラーとなります。このことは、self
に対する呼び出しは (それが暗黙であっても、self
をつけて明示したものであっても)、(コントローラーを経由して) モデルを対象とすることを意味しています。このことによって、モデルの扱いに関するメソッドをコントローラーに追加したり、ビューに対して追加のメソッドを提供することが可能になっています。
Volt は MVC アーキテクチャよりも MVVM アーキテクチャに近いものです。そこでのコントローラーとは、ビューへのデータの受け渡しを行うものではなく、ビューのコンテキストを表すものだと言えます。Volt::ModelController
を使うと、コントローラーは自分の扱うことのできないメソッドを自動的にモデルに引き継ぎます。このことは利便性を高めてくれます。なぜなら、コントローラーにモデルをセットし、バインディングのメソッドから直接そのプロパティにアクセスすることが可能であるからです。例えば、{{ model._name }}
と書くのではなく、{{ _name }}
とすることができます。