Meteorで初めてのデータフィルタリング制御
本記事は公式チュートリアル11の内容に沿って説明するものです。
チュートリアルの目次
- 初めてのMeteorアプリ作成
- 初めてのMeteor Spacebarsでテンプレート
- 初めてのMeteor Mongoコレクション
- 初めてのフォームとイベント処理
- Meteorで初めてのコレクション更新と削除
- 初めてのMeteorアプリのデプロイ
- Meteorで初めてのモバイルアプリ (スキップ)
- Meteorで初めてのセッション変数
- Meteorで初めてのユーザアカウント
- Meteorで初めてのパーミッション制御
- Meteorで初めてのデータフィルタリング制御
今回でこの一連のチュートリアルは終わりです。
データの読み込み権限について
前回のチュートリアルでは、パーミッションの制御について学びました。明確には述べませんでしたが、このパーミッション制御は書き込み権限に関するものでした。読み込みに関しては、Meteor.methodsでは制御できません。
Meteorにおけるデータの読み込みは、DDPによって裏で行なわれます。そのため、書き込みの時のようにAPI呼び出しにおける制御とは別の方法で制御します。それがpublishとsubscribeです。publishはサーバがから送信するデータを指示し、subscribeでそれを受信します。通常の(例えばRESTでよく行う)Request-Response型の通信形態とは逆向きになります。
前回までのチュートリアルではpublish/subscribeは気にする必要がありませんでしたが、それはautopublishというパッケージのおかげです。autopublishはコレクションのすべてをサーバがpublishして、クライアントがそれをsubscribeするという仕組みです。
autopublishはサーバのデータをすべてクライアントにコピーするものです。もしアプリの設計としてデータサイズが小規模でデータがすべて見えて構わない場合は、autopublishを使い続けることでも問題ないはずです。
一方、データの一部のみを見せたい場合は、autopublishではなく独自のpublishを自前で定義することになります。
PublishとSubscribeで制御する
初めにautopublishを外します。
meteor remove autopublish
で削除されます。この状態でアプリの動作を確認すると、今まで見えていたデータが見えなくなっているはずです。
まず、autopublishと同等の状態に復元します。publishはsample-app.jsのTasks = new Mongo.Collection("tasks");
の直後に次のコードを追加してください。
|
|
これは”tasks”と言う名前でTasksコレクションのすべてを送信するものです。次にこれを受け取るsubscribeをsample-app.jsのif (Meteor.isClient) {}
のブロック内の先頭に追加してください。
Meteor.subscribe("tasks");
これで”tasks”でpublishされたコレクションを受け取ります。この2つの修正でautopublishを外す前の状態と同等になったはずですので、動作を確認しましょう。
修正したコードはこちらと同じ(コメント除く)になっているはずです。
プライベートタスクを実装する
publishでデータのフィルタリングを制御する例として、プライベートタスクを実装します。プライベートタスクは、タスクの所有者のみが見ることのできるタスクで、privateプロパティで識別するようにします。
最初にプライベートタスクにするかどうかの切替ボタンを作ります。sample-app.htmlのtaskテンプレートのcheckboxの直後に次のコードを追加します。
isOwner
はこれから作るヘルパーです。トグルボタンでプライベートタスクと今まで通りのパブリックタスクを切り替えるようにしています。
プライベートタスクの場合は見ためも変えるようにしてみましょう。sample-app.htmlのtaskテンプレート内の1行目を次のように変更します。
次に、sample-app.jsを修正します。まず、isOwner
ヘルパーをTemplate.task.events({})
のブロックの前に下記のように追加します。ブロックの外です。
|
|
さらに、トグルボタンのイベント処理をTemplate.task.events.({})
のブロック内の最後に追加します(追加前の最後のアイテムにカンマ”,”をつけて区切ることを忘れずに)。
|
|
このsetPrivate
はMeteor.methods({})のブロック内の最後に追加します(追加前の最後のアイテムにカンマ”,”をつけて区切ることを忘れずに)。
|
|
setPrivate
でデータを変更できるのはそのデータの所有者のみにしたいため、まずそれをチェックしてからTasks.update()
を呼び出しています。findOne
はデータを一つだけ取得する関数です。
privateプロパティでpublishを変更
さて、privateプロパティができたので、プライベートタスクは他人からは見えないようにしましょう。そのためにはsample-app.jsを次のように修正します。
先ほど入力した
|
|
を、次のコードで置き換えます。
|
|
MongoDBのクエリが多少複雑ですが、privateが設定されていないか、所有者が自分であるタスクをコレクションから抽出するようになっています。
Meteor.methodsの定義の変更
プライベートタスクができたので、タスク完了の変更やタスクの削除についてもプライベートタスクについては所有者しか操作できないように制限しましょう。
sample-app.jsのMeteor.methodのdeleteTask
とsetChecked
を次のように修正してください。
|
|
このコードではパブリックタスクは誰でも削除できるようになっています。パブリックタスクでも所有者のみが削除できるようにする修正も可能です。
最終的なコード
すべての修正を終えたファイルは、このHTMLファイルとこのJavaScriptファイルになっているはずです。コメントや空行の有無などの違いはあってもコードとしては同一になっているかを確認するとよいでしょう。
動作を確認する
複数のユーザを作成して、それぞれプライベートタスクを作成し、互いに他人のプライベートタスクを見ることができないことを確認しましょう。
また仮にすべてのタスクをpublishするようにした場合でも、他人のプライベートタスクを完了したり削除したりできないことを確認しましょう。このとき、Optimistic UIにより一瞬変更が有効になったように見えて、すぐに戻されるという現象を確認できるかもしれません。
確認項目
- deleteTaskメソッドが正しく例外処理すること
- setCheckedメソッドが正しく例外処理すること
まとめと今後の学習法
以上で、一連のチュートリアルをすべて終了しました。これでMeteorの基本的な仕組みを学習できました。
Meteorには他にも例題が用意されています。
meteor create --example todos
meteor create --example localmarket
とすることでプロジェクトディレクトリが作成されますので、これらのコードを読んでみることも参考になるでしょう。
Meteorのマニュアルはhttp://docs.meteor.com/にあります。Basic Docsは分量が少なめなので素直に上から読んでみるとよいかもしれません(英語ですが)。Full APIは何か調べたいときに参照するのがよいのではないでしょうか。