技術書共有アプリにユーザーのプロフィールを入力できるようにした。

f:id:daigakukabuu:20181127192156p:plain 

これはPugのファビコンです。可愛いですね。

前回このよううな記事を書きました。

 

www.so-hack.com

 

この中で改良点として考えていた、ユーザープロフィールの編集を実装する

ということをやていこうと思います。

目次

プロフィール編集フォームの実装

まずはじめにプロフィールを編集する時の画面を作成します。

extends layout
block content
h3.my-3 Edit Profile
p #{geek.profile}
form(method="post", action=`/users/${user.userId}?edit=1`)
div.form-group
label(for="profile") Your Profile
textarea(name="profile" rows="4")#profile.form-control
div.form-group
button(type="submit").btn.btn-info Save

このアプリではテンプレートエンジンとしてExpressで動作するPugを利用しています。テンプレートエンジンを使うことで効率的にマークアップを行うことができます。

これでプロフィール設定画面にプロフィールを入力するためのテキストエリアとSaveボタンが実装されます。

Getting Started – Pug

コンテンツ部分以外のheadやbodyはすでに作成したlayout.pugにて他のページと共通のものを与えてあります。

doctype html
html
head
title= "Share Shelf"
meta(charset="utf-8")
meta(http-equiv="X-UA-Compatible" content="IE=edge")
meta(name="viewport" content="width=device-width, initial-scale=1")
link(rel='stylesheet',
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css",
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm",
crossorigin="anonymous")
link(rel="stylesheet", type="text/css" href="stylesheets/style.css")
body
nav.navbar.navbar-light.bg-light
div.navbar-header
a(href="/").navbar-brand.nav-link Share Shelf
ul.navbar-nav
if user
li.nav-item
a(href="/logout").nav-link Sign out #{user.username}
else
li.nav-item
a(href="/login").nav-link Sign in
div.container
block content
footer.fixed-bottom
div.container
p.text-muted Please sticky footer content here.
script(src="/javascripts/bundle.js")

ハンドラをRouterオブジェクトに登録

次にこのページを開くためのハンドラをRouterオブジェクトに登録します。

users.js

//ルーティングを行う
router.get('/:userId/edit', authenticationEnsurer, (req, res, next) => {
User.findOne({
where: {
userId: req.params.userId
}
}).then((user) => {
if (isMine(req, user)) {
res.render('profile', {
user: user
});
} else {
const err = new Error('You are not authorized to edit this profile');
err.status = 404;
next(err);
}
});
});
//ユーザー自身かを確認
function isMine(req, user) {
return user && parseInt(user.userId) === parseInt(req.user.id);
}

URLからUserIdを拾ってUserデータからそのIdのユーザーを絞り込みそのデータを返します。

UserIdと今ログインしている人のIdを比較して、同じ場合は編集画面を開き、異なる場合はエラーを返すようにしました。

ここまでの段階で読み込んでみると、

f:id:daigakukabuu:20181127174733p:plain

編集画面を開くことができました。

編集を反映させる

次に編集したものを保存して反映できるようにします。

先ほどのusers.jsファイルにPOSTされた時のルーティング処理を追加します。

ユーザーのページを開きつつ、profileを更新しています。

router.post('/:userId', authenticationEnsurer, (req, res, next) => {
console.log(req.body.profile);
Book.findAll({
where: {
createdBy: req.params.userId
},
order: [['"updatedAt"', 'DESC']]
}).then((books) => {
if (books) {
User.findOne({
where: {
userId: req.params.userId
}
}).then((user) => {
if (user && isMine(req, user)) {
if (parseInt(req.query.edit) === 1) {
user.update({
profile: req.body.profile
});
res.render('user', {
books: books,
//user: req.user,
user: user,
geekid: req.params.userId,
geek: user
});
} else {
const err = new Error('Bad request');
err.status = 400;
next(err);
}
} else {
const err = new Error('You are not authorized');
err.status = 404;
next(err);
}
});
console.log(req.params);
} else {
const err = new Error('Books not posted');
err.status = 404;
next(err);
}
});
});

f:id:daigakukabuu:20181127192029p:plain

こんな感じでプロフィールが表示されるようになりました。

ここにその人のやっていることや経歴を書けば、よりその人の本棚が参考になりますね!

コメントを残す