アプリ関連ニュース
- 2022年3月18日
- 技術情報
Laravelのフォームリクエスト: prepareForValidation
今回は、Laravelで検証を行う前にリクエストデータを操作することについて話したいと思います。
フォームのリクエスト例
まず、記事の投稿を保存するためのフォームリクエストの例から見てみましょう。入力に適用されるルールに注目してください。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|max:200',
'body' => 'required',
'tags' => 'required|array|max:10',
'is_published' => 'required|boolean',
'author_name' => 'required',
];
}
}
ここで、ユーザーが投稿を作成するためにフォームを送信し、次のような入力データを渡したと仮定します。
[
'title' => 'My articles post',
'body' => 'This is the <script>alert('Alert!')</script> articles body.',
'tags' => 'laravel,code,updates',
'is_published' => 'true',
'author_name' => 'Ami',
]
tagsはカンマ区切りの値のリストとしてフロントエンドから送信され、is_publishedの入力は文字列として解釈されます。どちらも、コンテンツの観点からは正しいにもかかわらず、形式が正しくないだけで検証は失敗します。
さらに、titleにタイプミスがあり、本文に悪意のあるコードが含まれているように見えます。技術的にはこれらはバリデーションの問題ではないと言えますが、ユーザーを自分自身から救い、アプリケーションを保護する手助けをすることは可能です。
prepareForValidation
このメソッドはprepareForValidationという適切な名前で、デフォルトのアクションを持ちません。つまり、オーバーライドするためだけに置かれたものです。
protected function prepareForValidation()
{
// no default action
}
ベースとなる FormRequest クラスは Request クラスを継承しているので、 merge ヘルパーメソッドにアクセスし、必要な入力値だけを更新することができます。また、入力値そのものにクラスのプロパティのようにアクセスすることもできます。
protected function prepareForValidation()
{
$this->merge([
'title' => fix_typos($this->title),
'body' => filter_malicious_content($this->body),
'tags' => convert_comma_separated_values_to_array($this->tags),
'is_published' => (bool) $this->is_published,
]);
}
値はリクエスト自体で更新されるので、バリデーションを行った後にコントローラでどのようにアクセスしても、操作された値が戻ってくることになります。
[
'title' => 'My blog post', // 誤字を修正しました!
'body' => 'This is the post body.', //悪質なコンテンツは削除されました!
'tags' => ['laravel', 'code', 'updates'], // 配列になりました!
'is_published' => true, // 今はブール値です!
'author_name' => 'Ami', // 相変わらずです。
今回はということで終わります。
By Ami
asahi at 2022年03月18日 10:00:00
- 2022年3月17日
- Web Service
Vue.jsの実用的なヒント
開発時にトリックを使用できれば、開発はよりスマートになり、時間を短縮できます。この記事では、Vuejsの最高のトリックを共有するつもりです。
1つのcomponentを複数のルートで使用する
複数のルートが同じVue componentに解決されることは、開発者が遭遇するかなり一般的な状況です。
しかし、問題は、Vueがアプリを最適化し、新しいコンポーネントを作成する代わりに、既存のコンポーネントを再利用することです。そのため、同じコンポーネントを使用するルート間で切り替えようとしても、何も変わりません。
router.js
const routes = [
{
path: "/a",
component: ArticleComponent,
},
{
path: "/b",
component: ArticleComponent,
},
];
これを修正するには、要素に:keyプロパティを追加する必要があります。これはApp.vueファイルにある可能性があります。これは、ページが異なる場合に routerが認識するのに役立ちます。
App.vue
<router-view :key='$route.path' />
これで、アプリは既存のコンポーネントを再利用せず、ルートを切り替えるときにコンテンツを更新します。
小道具をタイプのリストに制限する
プロップ定義で「バリデーター」オプションを使用すると、プロップを特定の値のセットに制限できます。
export default {
name: 'Image',
props: {
src: {
type: String,
},
style: {
type: String,
validator: s => ['square', 'rounded'].includes(s)
}
}
};
この「validator」関数は小道具を受け取り、小道具が有効かどうかにかかわらず、trueまたはfalseのいずれかを返します。
single スコープスロットの省略形
スコープスロットはとても楽しいですが、それらを使用するには、多くの template タグも使用する必要があります。
幸いなことに、それを取り除くための速記がありますが、それは単一のスコープスロットを使用している場合に限られます。
<DataTable>
<template #header="tableAttributes">
<TableHeader v-bind="tableAttributes" />
</template>
</DataTable>
次のように書き直すことができます。
<DataTable #header="tableAttributes">
<TableHeader v-bind="tableAttributes" />
</DataTable>
シンプルでわかりやすく、すばらしい。
すべての小道具を子コンポーネントに渡す
小道具と言えば、親 componentからその子の1つにすべての小道具を渡す方法を知っておくと便利です。
簡単です。instanceのプロパティを覚えておく必要があります。
<child-comp v-bind="$props"></child-comp>
local スタイルと global スタイルを組み合わせる
通常、スタイルを操作するときは、スタイルを単一の component にスコープする必要があります。
<style scoped>
.component {
background: green;
}
</style>
ただし、ピンチでは、スコープのないスタイルブロックを追加して、必要に応じてグローバルスタイルを追加することもできます。
<style>
/* Applied globally */
.component p {
margin-bottom: 16px;
}
</style>
<style scoped>
/* Scoped to this specific component */
.component {
background: green;
}
</style>
v-forでの破壊
v-forで分解できることをご存知ですか?
<li
v-for="{ name, id } in users"
:key="id"
>
{{ name }}
</li>
次のようなタプルを使用することで、v-forからインデックスを取得できることがより広く知られています。
<li v-for="(movie, index) in [
'Lion King',
'Frozen',
'The Princess Bride'
]">
{{ index + 1 }} - {{ movie }}
</li>
オブジェクトを使用するときは、キーを取得することもできます。
<li v-for="(value, key) in {
name: 'Lion King',
released: 2019,
director: 'Jon Favreau',
}">
{{ key }}: {{ value }}
</li>
また、この2つの方法を組み合わせて、キーだけでなく、プロパティのインデックスも取得することが可能です。
<li v-for="(value, key, index) in {
name: 'Lion King',
released: 2019,
director: 'Jon Favreau',
}">
#{{ index + 1 }}. {{ key }}: {{ value }}
</li>
カスタムV-model
デフォルトでは、v-model は “@input” イベントリスナーと “:value” プロップに対する構文糖の機能です。実は、どのイベントと値のプロップを使うかを指定できることをご存知でしょうか?Vueコンポーネントにmodelプロパティを指定することで、簡単に指定することができます。
export default{
model: {
event: 'change',
prop: 'checked'
}
}
複数のv-ifを使用しないでください
条件付きで複数の要素をレンダリングする必要がある場合もありますが、多くの場合、次のようなものを記述します。
<div v-if="condition">content</div>
<div v-if="condition">content</div>
<div v-if="condition">content</div>
もっとエレガントに書けるから不要なんです。
<template v-if="condition">
<div>content</div>
<div>content</div>
<div>content</div>
</template>
Arraysとobjectsを見る
ウォッチャーを使う上で一番厄介なのは、うまくトリガーできないことがあることです。
通常は、ArrayやObjectをウォッチしようとしているのに、deepをtrueに設定していないことが原因です。
export default {
name: 'ColourChange',
props: {
colours: {
type: Array,
required: true,
},
},
watch: {
// Use the object syntax instead of just a method
colours: {
// This will let Vue know to look inside the array
deep: true,
// We have to move our method to a handler field
handler()
console.log('The list of colours has changed!');
}
}
}
}
Vue 3の反応性APIを使用すると、次のようになります。
watch(
colours,
() => {
console.log('The list of colours has changed!');
},
{
deep: true,
}
);
以上が、vuejsの開発における最高のトリックです。次回は、さらに多くのトリックを紹介する予定です。
By Tsuki
tsuki at 2022年03月17日 10:00:00
- 2022年3月17日
- 技術情報
DataTablesを使用したテーブル生成とサーバーサイド連携(5)
DataTablesを使用したテーブル生成方法とサーバーサイド連携方法をシェアしたいと思います。
今回はサーバーサイド側の処理でデータベースから取得したレコードをDataTables表示に反映させる部分を説明いたします。
データベースから取得したレコードをDataTables表示に反映
以下のようにレコード内容がa,b,c,d,e固定になっていた部分をテーブルから取得した
実際のレコードに書き換えます。
function user_datatables(Request $request) {
$rec_data = [];
//テーブルから取得した実際のレコードに書き換え
$query = Member::query();
$member_list = $query->get();
foreach($member_list as $member){
$row_data = [
'item1' => $member->id,
'item2' => $member->sei.$member->mei,
'item3' => $member->sei_kana.$member->mei_kana,
'item4' => $member->mail,
'item5' => $member->created_at->format('Y-m-d H:i'),
];
$rec_data[] = $row_data;
}
$draw = $request->draw;
$res_json = array(
'draw' => $draw,
'recordsTotal' => '57',
'recordsFiltered' => '57',
'data' => $rec_data,
);
return response()->json($res_json);
}
以下のようにテーブルから取得したレコードがDataTablesに反映されていることが確認できました。

ページング処理の追加
次にページング処理の作成方法を説明いたします。
サーバーサイドでページング処理を実装するために
・1ページあたりの表示件数
・何件目から表示するか
のデータが必要になりますが、これらのデータはDataTablesがpostしてくれます。
以下のように取得できます。
//1ページあたりの表示件数
$length = $request->length;
//何件目から表示するか
$start = $request->start;
Laravelでレコードの抽出処理をおこなう際に、それぞれの数値をlimitおよびoffsetに設定します。
$query->offset($start);
$query->limit($length);
またフロント側でページ番号の表示処理をおこなうためにサーバーサイドからレコードの全件件数を
返す必要がありますが、これはLaravelの以下のメソッドで取得できます。
//全件件数の取得
$total_cnt = $query->count();
次回は上記の設定をおこなったページネーションのサーバーサイド処理の説明をおこないたいと思います。
木曜日担当:nishida
nishida at 2022年03月17日 10:00:00
- 2022年3月16日
- Windows
Windows用の Direct Storage API がリリースされました
tanaka at 2022年03月16日 10:00:00
- 2022年3月15日
- 技術情報
Django REST Framework
Today I would like to share a brief explanation about Django REST framework. Let’s take a look.
Django REST framework is a powerful and flexible toolkit for building Web APIs. Its main benefit is that it makes serialization much easier. Django REST framework is based on Django’s class-based views. It adopts implementations such as class-based views, forms, model validator, QuerySet, etc.
Django REST Framework includes built-in API browser for testing out newly developed API. Web API developed with Django REST Framework is web browsable, supports a wide range of media types, authentication and permission policies out of the box. API’s display data can use standard function based views, or granular with powerful class based views for more complex functionality.
Good Features of Django REST framework
- Powerful Serialization that supports both ORM and non-ORM data sources.
- Web browsable API is very useful for developers.
- Authentication policies including OAuth1a and OAuth2 out of the box.
- Easy to customize validators, parsers and authenticators.
- Generic classes for CRUD operations.
- Clean and simple views for Resources by using Django’s new class based views.
- HTTP response handling, content type negotiation using HTTP Accept headers.
- Pagination simplifies the process of returning paginated data in a way that can then be rendered to arbitrary media types.
- Publishing of metadata along with querysets.
This is a brief introduction about Django REST Framework.
Hope you enjoy that.
By Asahi
waithaw at 2022年03月15日 10:00:00