vue router で忘れがちな設定
個人的メモ
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter); // <<ココ忘れがち
vue router で忘れがちな設定
個人的メモ
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter); // <<ココ忘れがち
Laravelのルートがかなり多くなってきて、記述が大変&各ルートごとに細かな認可をどうするか考えた所、DBで管理することにしまあした。
モデルのイメージ
※アクションは頻繁に追加/変更差込などありそうなので、name(ルート名)で紐付けしている
権限をユーザーに付与する中間テーブル
(その他通常のフィールド)
こんかい業務案件なのでアクセス少なく気にならない不可でそのままですが、toC向けアクセス多い場合は何かしらキャッシュ/ビルドの仕組み必要そう。
$actions = \App\Action::get(); //全てのアクション取得
foreach ($actions as $key => $action) {
$methods = explode(',', $action->method);
$uri = $action->uri;
$name = $action->name;
$middleware = explode(',', $action->middleware);
$controllerAction = sprintf('%sController@%s', $action->controller, $action->action);
Route::match($methods, $uri, $controllerAction)->name($name)->middleware($middleware);
}
ざっくりと以下のように処理してます、のちのち運用フェーズではSQL一発で軽く確認できるような仕組みにしたい。
//actionを取得
$actionName = $request->route()->action['as'] ?? false;
//Actionモデルに認可判定処理関数を何かしら実装。
if(!Action::isAllow($actionName)){
//権限無いよのエラー処理
}
MacCatalinaにして、ブラウザが急にネットワークにつながらなくなったりする
GoogleChromeで新しいタブを開いたり、他のアプリを開いたりするとことごとくだめ。
ターミナル開いてどんなにコマンドを叩いても
fork: Resource temporarily unavailable
のエラーが出る。いろいろ調べると開けるファイルや、起動プロセス制限があるみたいでそれに引っかかっている可能性型高そう。
以下の記事を参考にlimit(ファイルとプロセス数)を上げてみる。
MacOSX で fork: Resource temporarily unavailable エラーになる場合の対処法
https://blog.regonn.tokyo/programmer/2017–02–03-mac-osx-process/
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxfiles</string>
<key>ProgramArguments</key>
<array>
<string>launchctl</string>
<string>limit</string>
<string>maxfiles</string>
<string>200000</string>
<string>200000</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>limit.maxproc</string>
<key>ProgramArguments</key>
<array>
<string>launchctl</string>
<string>limit</string>
<string>maxproc</string>
<string>4176</string>
<string>4176</string>
</array>
<key>RunAtLoad</key>
<true />
<key>ServiceIPC</key>
<false />
</dict>
</plist>
一旦こちらで様子を見てみます。
MacBookProの外部ディスプレイの接続が途切れたり、認識しなかったりが多い。
MacBookProといつも4Kディスプレイを繋いでいるのですが、接続してもいつもつながらなかったり抜き差ししたり、差し込むポートを変更したりで消耗してました。(ほかにも接点復活剤でクレンジングしたりetc.)
今回ふと、ケーブルを疑って長いからなのかとか信号が弱いからなのかとか考えて違うケーブル買ってみることに、するとビンゴ次のケーブルに変えてから全く問題なくなりましたので困っている方にはオススメ。
本質的なケーブルの質なのか、接点の質なのかなぞですが、なんとなく短いほうが信号が強い感じがして1mのものを購入しました。もっと早く買っておけば案件でした。
LaravelでJsonでレスポンスする場合のリレーションを含める方法は、Model(Eloquent)のtoArray()をオーバーライド
前提知識
著者クラスがあったとして、booksのhasManyのリレーションと、年齢を返すageアクセサをtoJson()に含める例。
class Authoer extends Model{
public function books(){
return $this->hasMany(....)
}
public function getAgeAttribute(){
return ....
}
.............中略..................
public function toArray()
{
return array_merge(parent::toArray(), [
'books'=>$this->books,
'age'=>$this->age
]);
}
}
PhotoShopのテキストボックス内で色が違う場合のSVG書き出し方法。
タイトルの状態のテキストボックスをシェイプに変換すると色が一色になってしまう現象があったので、対処法。(なにかいい方法ないかなぁ。)
※1 複数の文字色を使っているテキストレイヤーをシェイプに変換すると、範囲の多い文字色にすべて変換されてしまうようでした。
Docker環境のLaravel5.5で、実行環境でDBのホスト名を切り替えたい場合
php_sapi_name()関数で環境を判定して /config/database.phpで切り替えて上げればOK
‘cli’ならポートフォワーディングしているのホスト(親機)の127.0.0.1で接続
(apacheモジュールの場合は’apache2handler’)
'mysql' => [
'driver' => 'mysql',
'host' => (php_sapi_name()=='cli')? '127.0.0.1':env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
Laravel よく使うものまとめ (ver5.5.x)
User::all(); //全て
User::where('role' , 'admin')->get(); //whereなど条件後のすべて
User::where('role' , 'admin')->first();
User::query()->chunk(100, function($users){
foreach($users as $user){
//
}
});
foreach (User::where('role', 'member')->cursor() as $user) {
//PDOStatement::fetchを利用して1行ごとに取得
}
//find系
$user = User::find(10);//id指定
$users = User::find([10,324]);//idリストで指定
$user = User::findOrFail(1); // 無い時 'ModelNotFoundException' 例外をthrow
$user = User::where('email', 'test@example.com')->findOrFail();
※ModelNotFoundException はスルーすると 404 を返す。
$users = User::withTrashed()->get(); //削除済も含める
$users = User::onlyTrashed()->get(); //削除済のみ
$user = User::withTrached()->find(1)->restore(); //restore()で削除を解除
User::find(1)->forceDelete(); //完全削除
//date関係
$user->updated_at = now(); // now()は Carbonインスタンスを返す
$user = User::find(1);
echo $user->updated_at->getTimestamp();
//集計
User::all()->count();
User::all()->max('age');
//追加
$user = User::create(['email' => 'test@example.com']);
$user = User::firstOrCreate(['email' => 'test@example.com']); //なければcreate
$user = User::updateOrCreate(['email' => 'test@example.com']); // update もしくは create
$user = new User();
$user->email = 'test@example.com';
$user->save();
//Update
$user = User::find(1);
$user->email = 'test02@example.com';
$user->save();
//Multiple Update (savedとupdated イベントが発行されない)
$users = User::where('type','admin')->update(['is_admin' => 1]);
//delete
$user = User::find(1);
$user->delete();
User::destroy(1);
User::destroy([1,20,345]);
User::where('updated_at' , '<' , '2018-01-01 00:00:00')->delete();
//Model
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model
{
use SoftDeletes;
protected $table = 'members'; //命名規則外の場合のテーブル名
protected $primaryKey = 'user_id'; //命名規則外の主キー
protected $guarded = ['id','password','email']; // or fillableで許可
protected $hidden = ['password','remember_token']; // 隠すもの
protected $dates = [
'created_at',
'updated_at',
'deleted_at'
];
public static function boot()
{
parent::boot();
self::updating(function ($model) {
$text = implode('_', [$model->name, $model->kana]);
$text = mb_convert_kana($text, 'KVas', 'UTF-8');
$text = preg_replace("/(\s| )/", "", $text);
$model->search_text = $text;
});
}
public function getFullNameAttribute(){
return $this->lastname . ' ' . $this->firstname;
}
public function setKanaAttribute($value){
$this->attributes['kana'] = mb_convert_kana($value, 'KV', 'UTF-8');
}
public function kaimyou(){
return $this->hasOne('App\Kaimyou');
}
public function role(){
return $this->belongsTo('App\Role');
}
public function items(){
return $this->hasMany('App\Item');
}
public function types(){
return $this->belongsToMany('App\Type');
}
}
//relation
$user = User::find(1);
$user->kaimyou(); // 1:1
$user->role(); // n:1
$user->items(); // 1:n
$user->types(); // n:n
$user->types()->withPivot('note'); //チェックボックスのその他の入力欄など
//relationのsave/create
$user->items->save($item);
$user->items->saveMany([ $item1 , $item2 ]);
$user->items->create(['name'=>'薬草']);
$user->items->createMany(['name'=>'薬草'],['name'=>'毒消し草']);
//親realationへの所属
$admin_role = Role::getAdmin();
$user->role()->associate($admin_role);
$user->save();
//n:nの関連付け / 切り離し
$user->types()->attach($type_id);
$user->types()->attach($type_id,['note' => '特殊波動攻撃']);
$user->types()->attach([
2,
32 => ['note' => '召喚呪術']
]); //複数をattache 1つ目は通常、2番目はnote付き
$user->types()->detach($type_id); //または [$type_id,$type_id]
$user->types()->detach(); //すべて切離
$user->sync([2 , 4 , 7]); //指定したものだけが残る。
$user->toggle([2 , 4 , 7]); //指定したものをトグル
//親の updated_atを自動的に変更
class Item extends Model
{
protected $touches = ['user'];
public function user(){
return $this->belongsTo('App\User');
}
}
//Eager ロード/withでget()するとquery回数が減らせる。
$users = User::with('role')->get();
foreach ($users as $user) {
echo $user->role->name;
}
//Eager load 複数
$users = User::with(['role','items'])->get();
foreach ($users as $user) {
echo $user->role->name;
var_dump($user->items);
}
//Eager loadのネスト
$users = User::with('items.supplier')->get();
foreach ($users as $user) {
foreach($user->items as $item){
echo $item->name;
echo $item->supplier->name;
}
}
//Eager load 条件付
if(まとめてロードしたい){
$user->laod('items');
}
//Scopeスコープ
class User extends Model
{
public function scopePublish($query){
return $query->where('publish',1);
}
public function scopeStatus($query , $status){
return $query->where('status',$status);
}
.
.
}
User::publish()->get(); //引数なし
User::status('draft')->get(); //引数有り
$users = User::get(); //コレクションで取得
$users->all(); //すべて返す
$users->avg('age');
$users->median('age');//中央値
$users->mode('age');//最頻値
$users->max('age');
$users->min('age');
$users->sum('point'); //合計
$users->pluck('age'); // [40,34,28,22]
$users->pluck('age','id'); // ['1'=>40,'2'=>34,'3'=>28,'4'=>22]
$user = $users->random(); //ランダム
$users = $users->shuffle(); //シャッフルします。
$userPages = $user->chunk(10);//10ごとに分割
$allUsers = $users->concat($users2);
$users = $users->merge($users2);
$users = $users->reverse(); //反転(keyはそのまま)
$users = $users->sortBy('age');//年齢でソート コールバックでソートも可能/逆はsortByDesc
$users = $users->sortByDesc(function($user,$key){
return $user['point'] + $user['gold']; //ポイントとゴールドを合計した値で逆ソート
});
$users->mapWithKeys(function($user,$key) { //加工してkey,valueの形に
return [$user['id'] => $user['name']];
})->toArray();
$users->toArray();
$users->toJson();
$users->transform(function($user,$key){
return 加工したオブジェクト;
});
$users->values(); //keyを0から打ち直し
$user = $users->first();//最初
$user = $users->last();//最後
$user = $users->pop();//最後を削除して取り出し
$users->push($user);//最後に追加
$user = $users->shift(); //最初取り出し削除
$user = $users->firstWhere('role','admin');//最初の管理者
$user = $users->firstWhere('age' , '>=' , 40);//最初の40歳以上
$users = $users->slice(5,3); //5番目から3つ抜き出し
$users = $users->splice(5,3); //5番目から3つ抜き出して"削除"
$userGroups = $users->split(3); // 3つに分割
$users->isEmpty(); //また、$users->isNotEmpty()も有り
$users->contains('email', 'test@example.com'); //true or false またはcontainsStrict も有
$users->when(条件,function($users){ //条件がtrueの場合に実行 ->例えば、ある条件で攻撃力がみんな1.5倍
$users->transform(function($user,$key){
return $user->attack *= 1.5;
});
});
$users = $users->where('age',40); //40歳のみ
$users = $users->whereIn('age',[10,20,30]); // 10,20,30
$users = $users->whereNotIn('age',[18,28]); // 18,28以外
$users = $users->filter(function($user , $key){
return $user->age > 40; //40歳以上でフィルタ
});
$users = $users->reject(function($user , $key){
return $user->sex == 1; //男性を省く
});
$users->map(function($user,$key){ //加工して新しいコレクション
$user->point = random(1,100);
return $user;
});
$users->each(function($user,$key){
if(条件){
return false; // ループ終了
}
});
//macro 機能追加
Collection::macro('toUpper', function () {
return $this->map(function ($value) {
return Str::upper($value);
});
});
//経験値 500以上のユーザーモデルにlevelupメソッドを実行
$users = User::where('exp', '>', 500)->get();
$users->each->levelup();
(こう書ける?? 例外どうするか要検討)
User::where('exp' , '>' , 500)->get()->each->levelup();
//全員のポイントの総合計
$users = User::get();
return $users->sum->point;
(こう書ける?)
$users = User::get()->sum->point;
$arr = array_add(['name'=>'desk'] , 'price', 100); //['name'=>'desk', 'price' =>100]
$arr = array_collapse([1,2,3],[4,5,6]); // [1,2,3,4,5,6]
list($keys,$values) = array_divide(['name' => 'des,']); // $keys ['name'] , $values ['desk']
$arr = array_except(['name'=>'desk','price'=>100],['price']); //['name'=>'desk']
$result = array_random([1,2,3,4,5,6]); // どれか
app_path('Http/Controller'); // /path/to/project/app/Http/Controller
base_path('vendor/bin'); // /path/to/project/vendor/bin
config_path('app.php')/ // /path/to/project/config/app.php
$path = mix('css/app.css'); //バージョン付したMixファイルのパス
public_path(); //publicのパス
storage_path(); // strageディレクトリのパス
camel_case('foo_bar'); // fooBar
echo e('foo<br>bar'); // foo<br>
kebab_case('fooBar'); //foo-bar
snake_case('fooBar'); //foo_bar
$app = app(); //サービスコンテナを返す。
$user = auth()->user(); //authenticatorインスタンスを返す。
bcrypt('ヒミツのパスワード'); //ハッシュ表ジュウン
$value = config('app.timezone', $default); //コンフィグ値取得 /config/app.phpの'timezone'を取得
$env = env('APP_ENV'); // 取得
event(new UserRegistered($user)); //イベント発行
//redirect
abort(403); //例外
abort(403, 'Unauthorized.', $headers); //例外+メッセージヘッダー
return redirect($to = null, $status = 302, $headers = [], $secure = null);
return redirect('/home');
return redirect()->route('route.name');
return back($status = 302, $headers = [], $fallback = false); //引数はデフォルト return back();で戻る。
//URL
action('UserController@index'); // 例えば https://example.com/user
asset('img/photo.jpg'); //アセットへのhttp(s)://へのフルパス
route('user.edit',20); //例えば https://example.com/user/20
route('user.edit',['id'=>20,'type'=>'client']); //複数パラメータ Controllerのアクションで変数名($id,$type)で受取可
url('user/index'); //http://localhost/user/index
$value = session('key');
session(['chairs' => 7, 'instruments' => 3]);
$array = tap(Client::findOrFail(1), function ($client) use $name {
$client->title = $name;
})->toArray();
//infoレベル
info('Some helpful information!');
info('User login attempt failed.', ['id' => $user->id]);
//debugレベル
logger('Debug message');
//errorレベル
logger()->error('You are not allowed here.');
$now = now(); // Illuminate\Support\Carbonインスタンス
$value = old('value'); // 直前のフォーム
Macで外付けディスクを2つつないでそのままコピーしたら普通に激重たかったのでメモ。
rsyncでよいのか簡単だった。
$ rsync -avE /Volumes/旧HDD名/ /Volumes/新HDD名/
お題 mp4動画をチャプターごとに分割して音声ファイルにする。
追記:ワンライナーで分割するシェルスクリプトはこちら
ffmpegとmkvtookとmp4v2をインストール
$ brew install ffmpeg
$ brew install mkvtoolnix
$ brew install mp4v2
下ごしらえ、動画をチャプターに分割が重いので、事前に音声のみにする。(-vnはビデオなし、音声もこの時点でエンコード5.1ch > ステレオとかしても良いかも)
$ ffmpeg -i org.mp4 -vn -acodec copy tmp.mp4
mkvtoolnixについてくるmkvmergeコマンドで分割
$ mkvmerge -o output.mkv --split chapters:all tmp.mp4
今回音声コーデックがaacだったのですが、拡張子aacだとiTuneに取り込めず、m4aに
音声が5.1chとかだとm4aへ変換でエラーになるので、その場合は -ac 2 とかつけてステレオにしてあげるビットレートも-ab 480kとか指定してあげる
(今回はaacだったのでそのまま -acodec copyで流し込むだけ)
$ ffmpeg -i output-001.mkv -vn -acodec copy output-001.m4a
mp4v2のツールでタグ編集
$ mp4tags -A "アルバム名" -a "アーティスト名" -albumartist "アルバムアーティスト名" -t トラックNo 対象ファイル
Powered by WordPress & Theme by Anders Norén