【Laravel】ViewにMeta情報を渡す共通処理を実装する
話は飛躍しますが復習メモ。
DRY(Dont Repeat Yourself)の法則に則り、
共通処理や共通の変数については、何度も呼び出すのではなく
1度処理できるようにすると良い。
例えば、今回は全てのViewにHTMLへ埋め込む
Meta情報(titleやページ情報)を、共通処理にしたいとします。
Viewを呼び出すにあたり、共通経路はいくつかありますが
(親クラスやRouteなど)
auth認証など、毎回呼び出すものはMiddlewareが確実であり簡潔なので
全てのViewにデータを渡したい今回は
MiddlewareとView::shareメソッドを採用します。
※今回はDBにMeta情報全て入力済み、
MetaModelとmeta table使用の前提で進めていきます。
Middlewareを実際に作って、通し、実装する
①Middlewareを作る
php artisan make:Middleware GetMetaData //キャメルケース
緑色でsuccessと出ると、app/Http/Middlewareの下にGetMetaData.phpが
作成されているはずです。
②Middlewareを通す
Middlewareを使用するために、Kernel.phpで定義します。
今回は全てのViewに渡すとき、
つまりほとんどのHTTPリクエストに対応したいため
限定しない$middlewareプロパティへ追加します。
Kernel.php
protected $middleware = [ ... \App\Http\Middleware\GetMetaData::class //追加 ];
これで、全てのHTTPリクエスト時にGetMetaDataという
Middlewareが実行されるようになりました。
③Middlewareを実装する
それでは早速GetMetaDataの内容を実装していきます。
App/Http/Middleware/GetMetaData.php
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\View; //今回はView::shareを使用するので use App\Models\Meta as MetaModel; class GetMetaData { public function __construct() { $this->meta_model = new MetaModel; //MetaModelをインスタンス化 } public function handle(Request $request, Closure $next) { View::share(['meta' => $this->meta_model->getMetaData($request)]) //全てのViewに、metaという名前の配列を渡す ValueはMetaModelのgetMetaDataメソッドを呼び出す return $next($request); }
Meta.php
public function getMetaData($request)
{
$meta_id = $request[meta_id];
return $this->where('meta_id', $meta_id);
}
これで、Viewを表示するたびに
MetaテーブルからMeta情報を抽出する一連の流れが実装できました。
以上です。
【PHP】【twig】TwigBridge インストール〜コマンドまとめ(条件式、変数)
業務でtwig文を使っていたのですが
情報がバラバラだったのでまとめ。
目次
1.全体
インストール(twigbridge使用)
環境:Laravel5.5
GitHub - rcrowe/TwigBridge: Give the power of Twig to Laravel
Laravel使用されていれば、TwigBridgeの公式の通り実行すれば簡単!
英語なので補足で説明します。
Composerでインストール
composer require rcrowe/twigbridge
もしcomposerが既に導入されて入れば、このコマンドでinstallができます。
クイックスタート
まずは、configディレクトリのapp.phpを2箇所編集します。
'providers' => [ ...
/*
* Package Service Providers...//Laravelに登録する
*/ TwigBridge\ServiceProvider::class, ],
...
'aliases' => [ ...
/* Package Aliase */ //Twigという名前で簡単に呼び出せるようにする 'Twig' => TwigBridge\Facade\Twig::class, ],
こうして登録できたので、最後に、artisanコマンドを使用して
twigの設定ファイルを追加します。
php artisan vendor:publish --provider="TwigBridge\ServiceProvider"
これで下準備はおしまいです。
あとはresouse/viewディレクトリの傘下に、
.twigという拡張子がtwigのファイルを作成すればtwig形式で記載ができます。
私はlayoutsフォルダにdefaultを格納して、それらを継承しています。
継承
{% extends 'ファイルパス' %}
・別ファイルから継承する(複数はNG)
・親ブロックを子ブロックが上書きする
・{% block ブロック名%}〜{% endblock %}
挿入
{% include 'ファイルパス'%}
{% include 'aa/aa' with[ 'aa' : 'aa'] %} //引数も取れます
コメント文
{# ここにコメントを書く#}
CSRF対策
{{ csrf_field() }}
HTML文のエスケープ
{{ html文 | raw }}
その他
{{ 変数 | length }} //文字数
{{ dump() }} //PHPのdumpと一緒
2.変数
書き方
{{ 変数名 }}
※ただし条件式の中では{{}}は不要。(例:{% if post="hello" %})
定義方法
①同じTwig内で設定する
{% set 変数名='value' %}
・配列の場合は{% set array = [ A, B ] %}
・連想配列は{% set array = [ key : value ] %}
②Contorollerなどから渡す
変数:{{ 変数名 }}
配列:{{ 変数名.キー名 }} ※連想配列も可
▼例 (部分抜粋)
app/Controllers/PostController.php
$url = 'URLです';
$post = $this->post_model->getPostArray();
// 'id' => '1', 'title' => 'タイトル'
return view('post/show', [
'url' =>$url, //変数
'posr' =>$post ]; //配列
resouse/view/post/show.twig
<p>変数は「{{ url }}」です。</p>
<p>配列は idが{{ post.id }}で、
titleが{{ post.title }}です。</p>
出力結果
変数は「URLです」です。
配列は idが1で、titleがタイトルです。
その他
バリデーションエラーなど定型変数の時の書き方
・input_old('タグの名前') // セッションなどで確認フォーム利用時
・errors.first('タグの名前') //バリデーションエラー時
3.条件式
if文
{% if 条件式 %}
{% endif %}
・通常のif文が上記の書き方で使える
・条件式内で変数を定義した場合、条件文外では使用不能
・条件文内では、変数に{{}}はつけない
・else文、elseif文、複数条件の場合はandやorも使用可能
{% if 条件式A and 条件式B %}
{% elseif 条件式 %}
{% else %}
{% endif %}
for文
{% for i = 1 1..100 %}
{% endfor %}
・iは任意です
・連想配列の場合は{% for key, value in 配列名 %}
foreach文( ループ, for in で代用 )
{% for hoge in array %}
{% endfor %}
・arrayに任意の配列、hogeも任意の名前です
三項演算子
{{ 条件文 ? 処理A : 処理B }}
・条件文が正の時にA、誤の時B
例文
①テンプレート・変数を使用したページ
{% extends 'layout/user_default'%} |
②Emailのフォーム(一部抜粋)
<div class="form-group"> |
公式リンク
Documentation - Twig - The flexible, fast, and secure PHP template engine
以上
【PHP/Laravel】エンジニア歴1ヶ月の入門まとめ
Webエンジニアという職種について約1ヶ月がたちました。
本記事では1ヶ月たった自分が1週目の自分に教えられれば
より早い学習ができたのではないかと思う内容を復習がてら記載します。
この記事は正しいことが目的ではなく、
初心者が他の入門者により早く、考えてwebアプリを動かすための一助を
提供することを目的としています。
学術的、より正しく学びたい方は本や学校をご利用ください。
念のためおすすめの読者は下記です。
★ main: 独学でググってコピペして動かせる人
ドットインストールや参考書などで何か作ったことがある人
▼ min: PHPもしくはRubyの環境構築はググればできる人
目次
①MVCの使い方と基本的なwebアプリケーションの流れ
エンジニアになって最もご指導いただいたのがMVCの使い分け。Laravel5.5環境。
入門者:MVCそれぞれの役割を知っている。Contorollerにメソッド全部書く。太る。
初心者:MとCをDBに関連するか否かで書き分ける。←私は今ここ
それ以上:レベルの高いパターンなど考えるらしい(ごめんなさい知らない)
入門者についてはドットインストールや参考書が多くあるので初心者版を記載します。
▼ 簡易版はよくあるので、ちょっと詳しく図解。
大事なのは、find($id)をModelが実施していることです。
DBからそのidを持ったPostデータを取って来るというDBに関わる作業を
Controllerから切り離しています。
リクエストはブラウザのURLの部分だと考えてください。
post/show/26というリクエストが送られます。
route/web.phpの同リクエスト部分にヒットします。
>> route/web.php
Route::get('/post/show/{id}', 'PostController@show'); |
ここで、Routeはapp/Http/Controllers/PostControllerのshowメソッドへ
アクセスします。そして、そのshowメソッドが
app/Model/PostModelのgetPostメソッドを呼び出します。
関係する部分のみ抜粋してソースを書きます。
>> app/Http/Controllers/PostController.php
use App\Models\Post as PostModel ; } |
>> app/Models/Post.php
public function getPost($id){ |
はじめ、え、contorollerの中にpost_model??は???って思いました。
ですが、一度納得すると、こちらの方がMVCってこういうことか!と
わかりやすく感じるようになりました。
DBに関するものは、Modelを使用すると記載しましたが
具体化すると、
ー ー ー ー ー ー 前提と準備 ー ー ー ー ー ー ー
・Postというtableに入っているものはPostModelで操作します。
・Contorollerからリクエストに応じてPostのデータを取得するため、
PostModelの然るべきアクションを呼び出します。
・Modelのアクションを呼び出すため、
PostModelのクラスをPostController内でインスタンス化します。※
ー ー ー ー ー ー 実践 ー ー ー ー ー ー ー
・$this->post_model->getPost($id);
このPostControllerクラス($this)から、post_modelというインスタンスの
getPostというメソッドを呼び出します。(引数としてidを渡します。)
・PostModelのgetPostメソッドが、
$idに入った26というidを用いてDBのposts tableから id=26の
postデータを丸ごと配列として取り出します。
今回はその取り出した配列をそのままreturnしているので、
呼び出した$postに代入されます。(=は右辺の結果を左辺に代入する演算子)
・代入された$postを用いて、post/showというviewをresponseします。
・ユーザーはブラウザで、resouse/view/post/show.htmlが表示されます。
※ オブジェクト志向の話が入ると長くなるので下の2記事がおすすめです。
プログラミング勉強中の人にオブジェクト指向とは何なのかを何となく伝えたい話 - かまずにまるのみ。
図解ではわかりやすくするために分けましたが、
一時的な変数に入れているだけなので、こんな風に省略もできます。
public function show($id){ |
これは後のリーダブルコードで詳しく書きます。
長々と書きましたが、とりあえずPost-tableからデータ入れたり出したり更新したり削除(いわゆるCRUD)したいときは、Controllerに直接書かずにModelに書こうね!!
ControllerからModelを呼び出せるようにした方がMVCフレームワークだよね!!
ということが言いたかったわけです。
演算子の意味がわからない人はこれを読みましょう。
- 作者: 小川雄大,柄沢聡太郎,橋口誠
- 出版社/メーカー: 技術評論社
- 発売日: 2010/11/12
- メディア: 大型本
- 購入: 32人 クリック: 1,065回
- この商品を含むブログ (59件) を見る
②名前空間・クラス・メソッド・コントローラ・モデルの書き方
最低限のwebアプリケーションを作るのに必要ですが
情報がバラバラでわかりづらかったこの辺りをまとめます。
まずはソースコードと一緒にざっくり説明入れます。
<?php use App\Http\Controllers\BaseController;
public function __construct(PostModel $post_model) { $this->post_model = $post_model; } //publicは他のクラスなどどこからでも参照できるメソッド。 public function show($id) //メソッドの作り方: { return view('post/show', ['post' => $post]); // return 返り値 呼び出した奴にそのまま返り値が届きます。 } } |
③リーダブルコード(命名規則/コメント/リーダブルコード)
⑴命名規則は命です
ControllerやModelを作ろうとして、どんな名前にしようか分からなかった経験はありませんか?
今回は設定より規約という概念に則り記載します。詳しくは下記
簡単にいうとpostsテーブルにひもづくのは
PostモデルだとLaravelは知っています。
Modelでこのテーブルからデータを取ってくる、
と定義しなくてもid=26のデータですよと勝手にpostsテーブルを覗いてくれます。
具体的に見ると下記。
Model:Post.php、MsCountry.php 単数形・キャメルケース。
Table:posts、ms_countries 複数形・小文字・スネークケース。
Controller:PostController.php (複数形が主流との噂ですが単数も可)キャメルケース。
Class:BaseController キャメルケース。
Method:publlic function saveAndGetId(ココ) はじめが小文字のキャメルケース。
変数:$search_word 小文字のスネークケース。
とにかくコードやコメントを読む必要のないような
ものすごくわかりやすい名前をつけましょう。必要ならば名前が冗長でも構いません。
PGがコードを書くのと、それを読むのとでは後者の方が回数が多いので
保守性のあるコードを書きましょう!!!(口すっぱくご指導いただきました)
(2)コメントをかこう:
初心者のうちは毎行書いても良いくらいだと言われました。
人が読むソースコードを書くため、必ずコメントを書きましょう。
特に、メソッドの前には必ず記載します。書き方の一例を記載します。
/** // はじまり
* 特定単語によりPostデータを検索し結果を返す //1行目:メソッドの説明文
* //2行目:空行
* @params varchar $search_word //3行目:@params 種類 引数
* @return array $seach_result //4行目:@return 種類 返り値
* @access public //5行目:@access アクセス権限
*/ // おわり
public function create{ 〜
参考:
【PhpDoc】コメントの書き方のまとめ – 小俣泰明(タイメイ)blog
⑶リーダブルコード
まずこれを読みましょう。
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
- 作者: Dustin Boswell,Trevor Foucher,須藤功平,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/06/23
- メディア: 単行本(ソフトカバー)
- 購入: 68人 クリック: 1,802回
- この商品を含むブログ (138件) を見る
そして書き方の規約を学び、合わせて書きましょう。
PSR-2 コーディングガイド(日本語)|北海道札幌市のシステム開発会社インフィニットループ
・命名規則を守る
・コーディングガイドに則る
・(DRY)何度も書く定数・変数は定義する。
− 保守の時に変更が生じた場合に極力書き直すコストが減るように!
・何度も書くメソッドは切り分けで親コントローラーに書いて継承
・メソッドは一機能が原則、複数になる場合はprivateで切り分ける
・インデントを揃える
・空白も揃える (私はよくif文の空白を間違えます)
・一時変数を消す
コードは自分で書くものではなく、人が読むもの
保守性の高いコードを書きましょう(数回目)
とりあえず、これで初心者から入門者に近づけるといいな
リーダブルコードとか書いてる割に記事が冗長になってしまったので
今度Qiitaで書き直すことにします。
【MySQL】初心者の基本コマンド@Userやtable作成まとめ
MySQLの基礎コマンドよく見失うのでメモ。
【やりたいこと】
rootで初回ログイン/パスワード設定
ユーザー作成(+権限付与)
database作成
table作成など
※前提:MySQLはダウンロード済み
①rootで初回ログイン/パスワード設定
mysql -u root
はじめはパスワードがないので、rootでログインします。
コマンドがmysql>になれば成功です。
次にパスワードの設定をします。
set password for 'root'@'localhost' = password('任意のパスワード');
こちらで、ログアウトしてから再度ログインができれば成功です。
exit
mysql -u root -p #パスワードを使用してログイン
パスワードを聞かれますので、先ほど設定したrootのパスワードで
ログインができれば成功です。
②ユーザー作成・ログイン〜権限付与
まずはrootでログイン。
mysql -u root -p
ログインができれば早速ユーザを作りましょう。
create user dbuser identified by '任意のパスワード';
#dbuser/passwordは任意のユーザー名・パスワードへ変更してください。
mysqlのコマンドは必ず最後に「 ; 」が必要になります。
Query, OK と出てこれば作成完了です。
一度ログアウトして、早速ログイン。
exit;
mysql -u dbuser -p #dbuserというユーザ名と、パスワードを利用します
mysql>になっていればログイン成功です。
ですが、このユーザが権限を持っていないので、権限を付与します。
詳しい権限の種類やレベルは記載しませんが、
今回色々設定したいので全ての権限を付与します。
grant all on *.* to dbuser;
グローバルレベルのall権限が付与されました!
③database作成
create database database_name; #database_nameは任意のdatabase名
ログイン後、databaseを作ります。
できたか確認します。
show databases;
できたか見てみます。これでdatabase一覧が見れます。
use database_name; #database_nameというデータベースを使う
そして、database_nameというデータベースに移動します。
④table作成
tableを作ります。
安定のcreate。
create table table_names(id int, name varchar(20));
tabel_namesは任意のテーブル名を設定ください。
カラムなどにいくつか規則があるのでご注意ください。
ここで、カラムと挿入するデータ型を指定します。
id = カラムの名前(任意) / int = 整数
のため、このときはidというカラムに整数のデータ型を入れる。
ex. id = 1 など
ということになります。あとはデータ型や特徴さえ掴めば
テーブルが作成できますね。
初心者がよく使うのは
int:整数 / varchar:文字列(255字まで)
text:長い文字列(6万字くらいまで) / timestamp:日時
などですが、詳しくは下記サイトをご参照ください。
show tables;
今どんなテーブルがあるのか見られます。
そして、先ほどのテーブルへ移動します。
use tables(任意のテーブル名);
テーブル構造を見たいときは
desc tables(任意のテーブル名);
こちらで見られます。
また、insertデータを入れた後は、
select * from tables;
でも見れますし、整形して見たい場合は
select * from tables \G;
最後\Gをつけてあげると下記のような形で格納データが確認できます。
※Macではoption+¥マークでバックスラッシュが入力できます。
以上です。
【Ruby】Rubyで CSVファイルを処理するメモ
RubyでGoogle Spreadsheetを読み書きするメモ - Ruby on Rails 入門
上記記事の時、google spreadsheetからcsvファイルをダウンロードして
そのあとデータをjsonに整形することがあったのでメモ。
忘れないうちに自分用にメモさせていただきます
CSVからデータを取り出すにはRailsのtableとかforeachというメソッドが良いらしい。
tableはテーブル向けのインスタンスを返してくれるそうですが、
今回データを分けてHash化したかったので
foreachで1つ1つ取ってくる。
データを入れる用の配列を用意します
all = Array.new
hogehoges =
そして待ち焦がれたforeachの登場。
同フォルダ内のcsvファイルを読むよ、ヘッダーあるよ、dateに毎回入れるよ
CSV.foreach('table.csv',headers: true) do |data|
hogehoges.push data[1]
hogehoges.push data[2]
hogehoges.push data[3]
end
という感じ。
重複して欲しくなかったり分けたかったりしたので
compactやuniqを使用して最終的には下記になりました。
hashに全部入れて、jsonで返して終わりです。
#cording = UTF-8
require 'csv'
require 'json'
all = Array.new
hogehoges =CSV.foreach('table.csv',headers: true) do |data|
hogehoges.push data[1]
hogehoges.push data[2]
hogehoges.push data[3]
endnewhogehoges =hogehoges.compact.uniq
x = 1
y = 0newhogehoges.each do |neweq|
h = Hash["id", x, "name", neweq]
all.push(h)
x += 1
y += 1
endputs all.to_json
備忘録。
【Ruby】RubyでGoogle Spreadsheetを読み書きするメモ
【やりたいこと】
GoogleSpreadsheetにターミナルからアクセスをする。
様々な方法で挫折することも多々だったので現時点で上手くいった方法をメモ。
※Googleでログインしていて、
任意のSpreadsheetにアクセスできる状態が前提です。
google_driveのgemを使うのが一番良さそう。
gem install google_drive
Githubに情報たくさん載ってました。
OAuth認証だと何かと怒られるのですが
config.jsonでアクセスすれば一発でした。
google_driveを呼び出して、config.jsonファイルにアクセスするrubyファイルを作成。
require "google_drive"
GoogleDrive::Session.from_config("google_drive_config.json")
実行する
ruby setup.rb
アクセスするURLが表示されるので、
アクセスして authorization codeをコピー・ターミナルで入力。
→jsonファイルが作成されました。一番早かったです。
アクセス方法などは下記記事参照。
config.jsonを呼び出して、キー指定、
もしくはGoogleDriveのフォルダやブック、シート名を指定すれば
一発で指定のワークシートへアクセスできます。
ws = session.spreadsheet_by_key("pz7XtlQC-PYx-jrVMJErTcg").worksheets[0]
参考にさせていただきました。
RubyからGoogleSpreadsheetに書く - お手軽編 - Qiita
公式Github
GitHub - gimite/google-drive-ruby: A Ruby library to read/write files/spreadsheets in Google Drive/Docs.
google-drive-ruby/authorization.md at master · gimite/google-drive-ruby · GitHub
公式ドキュメント
File: README — Documentation for google_drive (2.1.5)
GoogleSpreadsheetへの読み書きは、worksheetを定義した上で使用可能。
あるシートから別シートへデータを写したいときなどは下記などで実行できます。
以下割と使ったのでまとめ。
p worksheet[1,1] #1行1列目を表示
worksheet[1, 1] = "aaa" # 1行目1列目に書き込み@item1 = worksheet[2, 1]
#worksheetの2行目1列目のセルを@item1に代入
worksheet2[2, 2] = @item1
#worksheet2のセル2行目2列目に@item1を代入
worksheet2.save
#保存p worksheet.num_rows # レコード数を取得
p worksheet.num_cols # カラム数を取得
以上
【Ruby】Ruby on Rails で 初心者がAjaxを使ってみる
【やりたいこと】
カテゴリーを変更すれば、Ajaxが 対応するカテゴリーのitem を取得し表示する。
※itemの部分のみが変更されるので、ページ変遷しない
【イメージ】
表示:ajax/search.html.erb
category1〜3で選択する
→api/controllers/ajax.controllerが呼び出される
→projectモデルがprojectsテーブルからデータ取得する
→選択したcategory_id=?のデータを表示する
※一旦シンプルに考えるためにアソシエーション無視して
category_idで同テーブルのデータを使用することとします
まずはコントローラを作成、その後必要なビューとかを作ります。
部分テンプレートを使用しました。
部分テンプレートを使用すると
ファイル名の先頭に「 _ 」をつけるという制限があるので、
今回は下記の通りファイルを作成しました。
・controllers/ajax_controller.rb #rails g controller ajax
・view/ajax/search.html.erb
・view/ajax/result.js.erb
・view/ajax/_search_result.html.erb
ajax_controller.rb
class AjaxController < ApplicationController
def search
@projects = Project.select(:category_id).distinct
#表示するカテゴリー番号を取得
enddef result
@projects = Project.where(category_id: params[:category_id])
#指定されたカテゴリーIDでprojectsテーブルを検索
end
end
search.html.erb
<%= form_tag({ action: 'result' }, remote: true) do %>
#view helperのform_tagは
#remoteオプションでsubmit時に非同期通信
<%= select_tag(:publish, options_from_collection_for_select(
@projects, :category_id, :category_id, '1')) %>
#option_from_collection_for_select = 選択肢をDBから生成するメソッド
<%= submit_tag '検索' %>
<% end %><ul id="result"></ul>
#結果を反映する
_search_result.html.erb(部分テンプレート)
<% @projects.each do |project| %>
#取って来たproject itemを1つずつ下記project.titleへ出力
<li><%= link_to project.title,
'http://aaa.aa.aaa.aa/index' %></li>
<% end %>
result.js.erb(部分テンプレートが作った結果をJavaScriptで応答)
$('#result').html(
"<%= escape_javascript(render 'search_result') %>")
#受け取った結果をhtmlファイルへ変換
route.rb
get '/ajax/result'
post '/ajax/result'
get '/ajax/search'
post'/ajax/result'
ルートにこれ追加したら一応なんとかいけました。
できました !