食料を安定的に獲得するために畑を作って栽培しようと思います。
まずは、草を刈って、種を採取します。
この種を育てると、小麦になります。
次にこれを植える場所。
まだ水を汲むことができないので、水の近くに畑を耕そうと思います。
なので、水野周りを整地します。
そして、クワで土を耕し、
種を植えます。
時間が経てば、麦になるはずです。
↑よかったらクリックおねがいします。
前回までの様子はこちら。
最新ソースコードはこちら。
https://github.com/takishita2nd/hotel-mng
まずは、テーブルの連携が正しくできるように、マイグレーションを修正しました。
実際に修正を行う際には、事前にロールバックを行うか、テーブルを書き換えるマイグレーションファイルを追加してください。
Schema::create('reserve_day_list_reserve_management', function (Blueprint $table) {
$table->increments('id');
$table->integer('reserve_management_id')
->foreign('reserve_management_id')
->references('id')->on('reserve_managements')
->onDelete('cascade');
$table->integer('reserve_day_list_id')
->foreign('reserve_day_list_id')
->references('id')->on('reserve_day_lists')
->onDelete('cascade');
$table->timestamps();
$table->engine = 'InnoDB';
$table->charset = 'utf8mb4';
$table->collation = 'utf8mb4_unicode_ci';
});
Laravelには、中間テーブルのネーミングルールが決まっており、それに合わないと、正しく中間テーブルを認識できません。
しかし、ネーミングルールがあっていれば、中間テーブルのモデルを定義しなくても、Laravelは中間テーブルを認識します。
各モデルの関数も修正します。
class ReserveManagement extends Model
{
protected $table = 'reserve_managements';
public function reserveDayLists()
{
return $this->belongsToMany('App\Model\ReserveDayList');
}
}
class ReserveDayList extends Model
{
protected $table = 'reserve_day_lists';
public function reserveManagements()
{
return $this->belongsToMany('App\Model\ReserveManagement');
}
}
これで、各モデルから連携先のモデルを直接参照することができます。
最後にリポジトリの修正を行います。
public function add($param)
{
$model = new ReserveManagement;
foreach($this->paramNames as $name)
{
$model->$name = $param[$name];
}
$model->save();
$model2 = new ReserveDayList();
$model2->day = $model->start_day;
$model2->save();
$model->reserveDayLists()->attach($model2);
for($i = 1; $i < $model->days; $i++)
{
$model2 = new ReserveDayList();
$model2->day = date('Y-m-d', strtotime($model->start_day.'+'.$i.' day'));
$model2->save();
$model->reserveDayLists()->attach($model2);
}
}
ちょっと変数名がよろしくありませんが、attach関数でLaravelは自身で中間テーブルを認識し、レコードの紐付けを行います。
逆に削除する場合は、
public function deleteById($id)
{
$model = $this->getItemById($id);
$model2s = $model->reserveDayLists()->get();
$model->reserveDayLists()->detach();
foreach($model2s as $model2)
{
$model2->delete();
}
$model->delete();
}
今度は逆にdetach関数で紐付けを解除します。
少し修正が発生しましたが、これで少ないコードでデータベースを簡単に扱うことができます。
↑よかったらクリックお願いします。
自前のマインクラフトサーバを立ち上げましたので、早速プレイします。
いでよ、マイワールド!
世界に入って最初にやることは、寝床の確保と、食料の確保です。
まずは適当に拠点を見つけて、木を殴ってアイテム化します。
そして、木から作業台を作成します。
作業台があれば、いろんなツールを作成することができます。
一通り揃えてしまいましょう。
次に羊さんをやっつけます。
羊毛と食料が確保できます。
羊毛はベッドを作るのに必要になります。
羊毛があれば作業台でベッドを作成できます。
次は、かまどを作成するために、石を採取します。
岩場が無ければ、地面を掘って石を確保するのも良いでしょう。
これで作業台でかまどが作れます。
食材は生のママでは効率が悪いですし、バッドステータス②鳴ることもあります。
なので、かまどで調理する必要があるのですが、
そのとき、木材を燃料にして食料を調理しても良いのですが、木材を燃やして木炭にすると、燃焼効率が良くなります。
それに木炭はたいまつの材料にもなりますし。
ここまで来れば、必要最低限の作業完了です。
↑よかったらクリックおねがいします。
FLASH11月26日号に、これから日本で頑張っていきます、という記事を見たあとなので、びっくりしました。

ご冥福をお祈りいたします。
前回までの様子はこちら
お次はテーブルのデータを削除する処理を作成します。
まずは、ルーティング。
Route::get('/management/{id}/conform', 'RegisterManagementController@conform');
Route::post('/management/delete', 'RegisterManagementController@delete');
/management/{id}/conformにアクセスすると削除確認の画面が、
/management/deleteにアクセスすると、実際に削除処理を行うようにします。
次は一覧画面に削除確認画面へのリンクを作成します。
<td>{{ Html::link('/management/'.$list->id.'/conform', '削除') }}</td>

そして、削除確認画面。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">削除確認</div>
<div class="panel-body">
{!! Form::open(['url' => action('RegisterManagementController@delete')]) !!}
{!! Form::hidden('id', $item->id) !!}
<table>
<tr>
<td>名前</td>
<td>{!! $item->name !!}</td>
</tr>
<tr>
<td>住所</td>
<td>{!! $item->address !!}</td>
</tr>
<tr>
<td>電話番号</td>
<td>{!! $item->phone !!}</td>
</tr>
<tr>
<td>人数</td>
<td>{!! $item->num !!}</td>
</tr>
<tr>
<td>宿泊日数</td>
<td>{!! $item->days !!}</td>
</tr>
<tr>
<td>宿泊日</td>
<td>{!! $item->start_day !!}</td>
</tr>
</table>
{!! Form::submit('削除') !!}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection

隠しパラメータにid番号を含め、formをSubmitしたときのパラメータにします。
次に、コントローラー。
/**
* 削除確認
*
* @return \Illuminate\Http\Response
*/
public function conform($id)
{
return view('register.conform', ['item' => $this->registerManagement->getItemById($id)]);
}
/**
* 削除処理
*/
public function delete(Request $request)
{
$this->registerManagement->deleteById($request->id);
return redirect('management');
}
削除確認では、URLのID番号を受け取り、そのIDからデータを参照し、Viewに返しています。
削除処理では、$requestにID番号が入っていますので、そのIDをリポジトリに渡して、削除処理を行ったあと、一覧画面にリダイレクトします。
次はリポジトリ。
/**
* 予約を削除する
*
* @return void
*/
public function deleteById($id)
{
$model = $this->getItemById($id);
$model->delete();
}
IDでモデルを検索して、delete()メソッドを実行すれば、そのデータはデータベースから削除されます。

これで削除処理が完成しました。
次は、この情報から予約スケジュールを作成する処理を作成していきます。
↑よかったらクリックお願いします。
何を思ったのかJava版のマインクラフトを買ってしまいました。

単体でプレイしてもいいのですが、せっかくなので、サーバを立ち上げて、いろんな環境からプレイできるようにしたい、と思いました。
まずは、サーバに、ダウンロードしたjarファイルを設置します。
実行するコマンドは、
$ java -Xmx1024M -Xms1024M -jar server.jar nogui
デスクトップ環境があれば、noguiオプションを取り除けば、GUIでいろいろ操作できるのですが、

こんな感じ。
ログも確認できる他、接続しているユーザーも確認できるし、ここからコマンドを入力して設定を変えることもできます。
しかし、VPS上で動かすならば、デスクトップ環境は無いので、このような画面は使用できません。
taki@taki-300-030jp:~/minecraft-server$ java -Xmx1024M -Xms1024M -jar server.jar nogui [20:01:20] [main/ERROR]: Failed to load properties from file: server.properties [20:01:20] [main/WARN]: Failed to load eula.txt [20:01:20] [main/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.
実行すると、こんなメッセージが表示されます。
どうやらEULAを承諾しないと動かすことができないみたいなので、同じディレクトリに生成されている、eula.txtの記述を変更しなければいけません。
eula.txtを開いて、
eula=true
と書き換えます。
Done (47.956s)! For help, type "help"
と表示されればサーバは稼働しています。
iptableを使用している方は、マインクラフト用のポートを開放しなければ、外部からアクセスできません。
サーバの実行ログから、使用されているポート番号は25565であることがわかりますので、外部からこのポートへのアクセスを許可します。
$ sudo iptables -A INPUT -p tcp -m tcp --dport 25565 -j ACCEPT $ sudo /etc/init.d/netfilter-persistent save
これでVPSを再起動しても、マイクラサーバにアクセスできます。(マイクラサーバプログラムは再起動させないといけませんが)
このままでは、URL(またはIPアドレス)がわかってしまえば誰でもサーバにアクセスできる状態となってしまいます。
なので、管理者が許可したアカウントだけサーバにアクセスできるように、ホワイトリストを設定しなければなりません。
ホワイトリストを有効にするには、サーバプログラムと同じディレクトリに生成された、server.propertiesを開き、
white-list=true
に書き換えます。
これで、ホワイトリストが有効になります。
もしくは、サーバのコンソールに、
/whitelist on
と、入力してもOKです。
こちらのほうが簡単かもしれません。
次に、ホワイトリストの登録を行います。
サーバコンソールに以下のコマンドを入力します。
/whitelist add [アカウント名]
これで、ホワイトリストの登録が行なえます。
あとはクライアント側から登録アカウント名でログインし、サーバにアクセスすればワールドに入ることができます。
逆に登録されていないユーザーはワールドに入ることができません。
これで一通りの設定は完了です。
細かい設定は、サーバのコンソールから
/help
と入力すれば、コマンド一覧が表示されますよ。
前回までの様子はこちら。
ソースコードはこちら。
https://github.com/takishita2nd/hotel-mng
今回は登録した内容を更新するところまでやります。
データを更新する前に、データを更新するページにリンクするように一覧画面を修正します。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">予約一覧</div>
<div class="panel-body">
<table>
<tr>
<th>名前</th>
<th>住所</th>
<th>電話番号</th>
<th>人数</th>
<th>宿泊日</th>
<th>宿泊日数</th>
<th>編集</th>
<th>削除</th>
</tr>
@foreach ($registerLists as $list)
<tr>
<td>{{ $list->name }}</td>
<td>{{ $list->address }}</td>
<td>{{ $list->phone }}</td>
<td>{{ $list->num }}</td>
<td>{{ $list->days }}</td>
<td>{{ $list->start_day }}</td>
<td>{{ Html::link('/management/'.$list->id.'/edit', '編集') }}</td>
<td>削除</td>
</tr>
@endforeach
</table>
</div>
</div>
</div>
</div>
</div>
@endsection

そして、ルーティングの設定も追加します。
Route::get('/management/{id}/edit', 'RegisterManagementController@edit');
Route::post('/management/update', 'RegisterManagementController@update');
更新フォームへのリンクと、実際にデータを更新するリクエストですね。
コントローラーには、以下の関数を追加します。
/**
* 編集処理
*/
public function edit($id)
{
return view('register.edit', ['item' => $this->registerManagement->getItemById($id)]);
}
/**
* 更新処理
*/
public function update(Request $request)
{
$param = $this->registerManagement->getParam();
$this->registerManagement->updateById($request->id,
[
$param[0] => $request->name,
$param[1] => $request->address,
$param[2] => $request->phone,
$param[3] => $request->num,
$param[4] => $request->days,
$param[5] => $request->start_day
]);
return redirect('management');
}
そして、リポジトリには以下の関数を追加。
// IDから予約を1件取得する
public function getItemById($id)
{
return ReserveManagement::where(['id' => $id])->first();
}
// 予約を更新する
public function updateById($id, $param)
{
$model = $this->getItemById($id);
foreach($this->paramNames as $name)
{
$model->$name = $param[$name];
}
$model->save();
}
「編集」のリンクのURLにデータベースのID番号が入っていて、それをコントローラーで受け取り、データベースからIDで参照して、データを取得します。
そして、取得したデータをViewに渡します。
実際に編集画面のViewはこちら。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">予約登録</div>
<div class="panel-body">
{!! Form::open(['url' => action('RegisterManagementController@update')]) !!}
{!! Form::hidden('id', $item->id) !!}
<table>
<tr>
<td>名前</td>
<td>{!! Form::text('name', $item->name) !!}</td>
</tr>
<tr>
<td>住所</td>
<td>{!! Form::text('address', $item->address) !!}</td>
</tr>
<tr>
<td>電話番号</td>
<td>{!! Form::number('phone', $item->phone) !!}</td>
</tr>
<tr>
<td>人数</td>
<td>{!! Form::select('num', ['1' => 1, '2' => 2], $item->num) !!}</td>
</tr>
<tr>
<td>宿泊日数</td>
<td>{!! Form::select('days', ['1' => 1, '2' => 2, '3' => 3, '4' => 4], $item->days) !!}</td>
</tr>
<tr>
<td>宿泊日</td>
<td>{!! Form::date('start_day', $item->start_day) !!}</td>
</tr>
</table>
{!! Form::submit('登録') !!}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection

見た目は登録と同じですが、デフォルト値を設定しているのが異なります。
コントローラーから受け取った値をデフォルト値として設定しています。
そして、登録ボタンを押すと、その情報がコントローラーのupdate関数に渡されます。
そして、その情報をデータベースに設定し、一覧画面にリダイレクトします。
これで更新処理が完成しました。
次回は削除処理を作りたいと思います。
↑よかったらクリックお願いします。
情報処理の資格を目指して勉強している人にとっては当たり前の話なんですがね。
パソコンの記憶領域には3種類ありまして。
と言う具合に分類されます。
レジスタは、CPUが直接扱うことができるデータの領域、
メモリは、そのCPUの計算結果の一時退避場所です。
これらは、電源をOFFにすると全て消えてしまいます。
なので、消えてしまうとマズいデータは全てストレージの領域に待避させます。
ストレージは、我々で言う、HDDとか、SSDと呼ばれる領域です。
各記憶領域のアクセススピードは、
レジスタ≫メモリ≫ストレージ
「≫」というのは、天地ほどの差があると言うことです。
パソコンはたくさんのアプリを起動すると、それだけ、沢山のメモリを使用します。
もし、このとき、必要なメモリのサイズを用意できなかったら。
OSは一番使用していないメモリの中のデータをストレージにコピーして、メモリの容量を確保します。
そして、必要になったとき、待避したストレージ上のデータをメモリに戻すという処理が発生します。
これは、情報処理の勉強をしている人ならわかるかもしれませんが、スワッピング(または、ページング)と呼ばれる処理です。
メモリが少ないとこの一連の処理が頻発します。
これが、パソコンの処理を重くしている一番の要因です。
なぜなら、通常のメモリアクセスより、ストレージにアクセスする方が遙かに遅いためです。
ここで、私が提案するのは、使用する用途によってわかりやすいように区別しようと言うことです。
例えば、
4GBというのは、主にスティック型PCに搭載される最低ラインのメモリサイズです。
これくらいならば、リモートデスクトップで開発用PCの画面を表示するだけならば、十分なスペックです。
というか、複数の画面を表示させようとするならば、それだけPCの処理が重くなります。十分なメモリサイズとは言えません。
しかし、8GBならば、ある程度のウインドウを開いても十分耐えられるでしょう。
文章作成に2画面使用する程度ならば、十分耐えられると言えます。
しかし、最近のインターネットブラウザは複数タブで使用される事が多いです。
このタブをたくさん開けば、それだけ、メモリが消費されることになります。
プログラマーならば、連絡用途と調べ物用途にたくさんのタブやウィンドウを開くことになりますので、それだけたくさんのメモリが必要になります。
でも、クリエイターレベルになるとそれだけでも足りません。
なぜなら、扱うデータファイルのサイズが大きいから。
複数の大規模な動画データを扱うならば、16GBでギリギリ、もしくは、それ以上のメモリが必要になるでしょう。
ちなみに、今のMAC Proだと、最大メモリは768GB。
最前線のYouTuber達はこのスペックで動画編集していると思って問題無いと思います。
今のPCのスペックでは、CPU自体の処理速度よりは、ストレージへのアクセス自体がボトルネック(一番処理が遅延している要因)と思いますので、
PCの処理が重いと感じ、様々な手を施しても改善しない場合は、メモリの増設とか、HDDをSSDに換装する、などの手を検討した方が良いかもしれません。
最近のホームページも重くなってきたし。
自分がPCを選ぶ場合は、まず最初にメモリのサイズを確認します。
ぶっちゃけ、CPUは世代や型番の違いによって、劇的に変化するわけではありません。
ストレージのサイズは後で外部HDD購入で増設できます。
あくまでも一番の遅延要因は、メモリ不足によるページング処理による遅延と言うことです。
なので、他のスペックよりも、何よりもメモリサイズを優先させます。
まぁ、これらは私の考えなので。
これからパソコンを購入したいと考えている人の参考になってもらえれば幸いです。
↑よかったらクリックおねがいします。
最新ソースはこちら
https://github.com/takishita2nd/hotel-mng
前回からの続きです。
今回はデータベースに登録するフォームを作成し、そこから実際にデータを登録するところまで作成します。
まずは、登録フォームの作成から。
フォームを作るには、ヘルパーを使うのがいいです。
$ composer require "laravelcollective/html":"^5.4.0"
これでフォームのヘルパーが使えます。
Viewはこんな感じで作成しました。
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">予約登録</div>
<div class="panel-body">
{!! Form::open(['url' => action('RegisterManagementController@store')]) !!}
<table>
<tr>
<td>名前</td>
<td>{!! Form::text('name') !!}</td>
</tr>
<tr>
<td>住所</td>
<td>{!! Form::text('address') !!}</td>
</tr>
<tr>
<td>電話番号</td>
<td>{!! Form::number('phone') !!}</td>
</tr>
<tr>
<td>人数</td>
<td>{!! Form::select('num', ['1' => 1, '2' => 2]) !!}</td>
</tr>
<tr>
<td>宿泊日数</td>
<td>{!! Form::select('days', ['1' => 1, '2' => 2, '3' => 3, '4' => 4]) !!}</td>
</tr>
<tr>
<td>宿泊日</td>
<td>{!! Form::date('start_day', \Carbon\Carbon::now()) !!}</td>
</tr>
</table>
{!! Form::submit('登録') !!}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection
Form::open()〜Form::close()までがフォームの部分です。
この間にいろいろ入力コントロールを入れます。

こんな感じで表示されます。便利。
登録ボタンを押したときの処理も追加します。
ルーティングの設定。
Route::get('/management/create', 'RegisterManagementController@create');
Route::post('/management', 'RegisterManagementController@store');
コントローラーの設定。
/**
* 入力フォーム
*/
public function create()
{
return view('register.create');
}
/**
* 登録処理
*/
public function store(Request $request)
{
$param = $this->registerManagement->getParam();
$this->registerManagement->add([
$param[0] => $request->name,
$param[1] => $request->address,
$param[2] => $request->phone,
$param[3] => $request->num,
$param[4] => $request->days,
$param[5] => $request->start_day
]);
return redirect('management');
}
$requestの中に、フォームに入力したデータが入ってます。
リポジトリからモデルに設定するパラメータを取得し、これらを連想配列に設定して、リポジトリに渡します。
その後、リダイレクトを行います。
次にリポジトリの設定。
private $paramNames = ['name', 'address', 'phone', 'num', 'days', 'start_day'];
// 予約を登録する
public function add($param)
{
$model = new ReserveManagement;
foreach($this->paramNames as $name)
{
$model->$name = $param[$name];
}
$model->save();
}
public function getParam()
{
return $this->paramNames;
}
パラメータ名を配列で持たせることによって、foreachで回せるし、コントローラーとの意識のズレも防ぐことができます。
もっとうまい方法があるかもしれないけど、これが精一杯じゃ。
これで、登録処理が動くようになりました。

↑よかったらクリックお願いします。