<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on ezaki3</title>
        <link>https://eza-s.com/blog/posts/</link>
        <description>Recent content in Posts on ezaki3</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <copyright>&lt;a href=&#34;https://creativecommons.org/licenses/by-nc/4.0/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CC BY-NC 4.0&lt;/a&gt;</copyright>
        <lastBuildDate>Sat, 15 Apr 2023 00:00:00 +0000</lastBuildDate>
        <atom:link href="https://eza-s.com/blog/posts/index.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>LaravelのテストでSQLiteからPostgreSQLに変更したらテストが通らなくなる件</title>
            <link>https://eza-s.com/blog/archives/401/</link>
            <pubDate>Sat, 15 Apr 2023 00:00:00 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/401/</guid>
            <description>はじめに ローカル環境でのテストでSQLiteを使っていたけど、PostgreSQL固有の機能を使用した実装を行った場合はSQLiteではテストできなくなるのでPostgreSQLに変更したところ、今まで通ってたテストが通らなくなる場合があります。ファイル単体のテストでは通るのに、ファイル指定をせずに一括で行った場合にエラーになるといった現象となります。
対策 対策1 phpunit.xmlのprocessIsolationをtrueにする
processIsolation=&amp;#34;true&amp;#34; 対策1を行った後に全体のテストを行うと、以下のエラーとなったケースがあります。
$ vendor/bin/phpunit PHPUnit 9.5.25 #StandWithUkraine Warning: Your XML configuration validates against a deprecated schema. Suggestion: Migrate your XML configuration using &amp;#34;--migrate-configuration&amp;#34;! EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE 61 / 1757 ( 3%) EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE 122 / 1757 ( 6%) EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE 183 / 1757 ( 10%) 省略 EEEEEEEESerialization of &amp;#39;Illuminate\Http\Testing\File&amp;#39; is not allowed 対策2 phpunit.xmlのbackupStaticAttributesをtrueにする（その場合、processIsolationはfalseで良い）
backupStaticAttributes=&amp;#34;true&amp;#34; </description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>ローカル環境でのテストでSQLiteを使っていたけど、PostgreSQL固有の機能を使用した実装を行った場合はSQLiteではテストできなくなるのでPostgreSQLに変更したところ、今まで通ってたテストが通らなくなる場合があります。ファイル単体のテストでは通るのに、ファイル指定をせずに一括で行った場合にエラーになるといった現象となります。</p>
<h2 id="対策">対策</h2>
<h3 id="対策1">対策1</h3>
<p>phpunit.xmlのprocessIsolationをtrueにする</p>
<pre tabindex="0"><code>processIsolation=&#34;true&#34;
</code></pre><p>対策1を行った後に全体のテストを行うと、以下のエラーとなったケースがあります。</p>
<pre tabindex="0"><code>$ vendor/bin/phpunit
PHPUnit 9.5.25 #StandWithUkraine

Warning:       Your XML configuration validates against a deprecated schema.
Suggestion:    Migrate your XML configuration using &#34;--migrate-configuration&#34;!

EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE   61 / 1757 (  3%)
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE  122 / 1757 (  6%)
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE  183 / 1757 ( 10%)
省略
EEEEEEEESerialization of &#39;Illuminate\Http\Testing\File&#39; is not allowed
</code></pre><h3 id="対策2">対策2</h3>
<p>phpunit.xmlのbackupStaticAttributesをtrueにする（その場合、processIsolationはfalseで良い）</p>
<pre tabindex="0"><code>backupStaticAttributes=&#34;true&#34;
</code></pre>]]></content>
        </item>
        
        <item>
            <title>Windowsでテキストエリアに入力した改行をLFに変換する</title>
            <link>https://eza-s.com/blog/archives/400/</link>
            <pubDate>Wed, 30 Mar 2022 00:00:00 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/400/</guid>
            <description>Laravelのバージョンは6です。
Windowsで入力フォームのテキストエリアに改行を入れるとCRLFとなるのですが、Laravelの文字数に関するバリデーションでCRとLFで2文字にカウントされるのをLFに変換して1文字でカウントされるようにする方法です。
調べてみるとFormRequestのvalidationDataをオーバーライドするやり方が見つかったのですが、変換処理は全ての入力に対して行いたいので、基底となるクラスを作成して継承させるか、Traitを作成してuseするか等が考えられます。そうなると現行システムに対して変更するファイルが多くなってしまうのと、そもそもFormRequestを使ってない箇所もあったのでapp/Providers/AppServiceProvider.phpに処理を書いてみました。
class AppServiceProvider extends ServiceProvider { private function convertCrlfToLf(&amp;amp;$results, $params, $prevKey = null) { foreach ($params as $key =&amp;gt; $value) { if ($prevKey) { $key = $prevKey . &amp;#39;.&amp;#39; . $key; } if (is_array($value)) { $this-&amp;gt;convertCrlfToLf($results, $value, $key); } else { $value = preg_replace(&amp;#34;/\r\n/&amp;#34;, &amp;#34;\n&amp;#34;, $value); data_set($results, $key, $value); } } } /** * Bootstrap any application services. * * @return void */ public function boot() { // windowsの場合、改行がCRLFで2文字としてカウントされるのでLFに変換する $results = []; $this-&amp;gt;convertCrlfToLf($results, request()-&amp;gt;all()); request()-&amp;gt;replace($results); // 以下省略 項目の多い入力フォーム等で、</description>
            <content type="html"><![CDATA[<p>Laravelのバージョンは6です。</p>
<p>Windowsで入力フォームのテキストエリアに改行を入れるとCRLFとなるのですが、Laravelの文字数に関するバリデーションでCRとLFで2文字にカウントされるのをLFに変換して1文字でカウントされるようにする方法です。</p>
<p>調べてみるとFormRequestのvalidationDataをオーバーライドするやり方が見つかったのですが、変換処理は全ての入力に対して行いたいので、基底となるクラスを作成して継承させるか、Traitを作成してuseするか等が考えられます。そうなると現行システムに対して変更するファイルが多くなってしまうのと、そもそもFormRequestを使ってない箇所もあったのでapp/Providers/AppServiceProvider.phpに処理を書いてみました。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AppServiceProvider</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">ServiceProvider</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">convertCrlfToLf</span>(<span style="color:#f92672">&amp;</span>$results, $params, $prevKey <span style="color:#f92672">=</span> <span style="color:#66d9ef">null</span>)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">foreach</span> ($params <span style="color:#66d9ef">as</span> $key <span style="color:#f92672">=&gt;</span> $value) {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> ($prevKey) {
</span></span><span style="display:flex;"><span>                $key <span style="color:#f92672">=</span> $prevKey <span style="color:#f92672">.</span> <span style="color:#e6db74">&#39;.&#39;</span> <span style="color:#f92672">.</span> $key;
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">is_array</span>($value)) {
</span></span><span style="display:flex;"><span>                $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">convertCrlfToLf</span>($results, $value, $key);
</span></span><span style="display:flex;"><span>            } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>                $value <span style="color:#f92672">=</span> <span style="color:#a6e22e">preg_replace</span>(<span style="color:#e6db74">&#34;/</span><span style="color:#ae81ff">\r\n</span><span style="color:#e6db74">/&#34;</span>, <span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">&#34;</span>, $value);
</span></span><span style="display:flex;"><span>                <span style="color:#a6e22e">data_set</span>($results, $key, $value);
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Bootstrap any application services.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return void
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">boot</span>()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// windowsの場合、改行がCRLFで2文字としてカウントされるのでLFに変換する
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        $results <span style="color:#f92672">=</span> [];
</span></span><span style="display:flex;"><span>        $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">convertCrlfToLf</span>($results, <span style="color:#a6e22e">request</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">all</span>());
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">request</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">replace</span>($results);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// 以下省略
</span></span></span></code></pre></div><p>項目の多い入力フォーム等で、</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#f92672">textarea</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;foo[bar][baz]&#34;</span>&gt;&lt;/<span style="color:#f92672">textarea</span>&gt;
</span></span></code></pre></div><p>のようにネストした配列にも対応させるため、再帰的に処理できるようにしました。</p>
]]></content>
        </item>
        
        <item>
            <title>Carbonで曜日を表示したい時</title>
            <link>https://eza-s.com/blog/archives/380/</link>
            <pubDate>Sat, 14 Mar 2020 12:08:24 +0900</pubDate>
            
            <guid>https://eza-s.com/blog/archives/380/</guid>
            <description>Carbonで曜日を表示する方法を調べてみると、
$dt = new Carbon(); echo $dt-&amp;gt;formatLocalized(&amp;#39;%Y年%m月%d日（%a）&amp;#39;); のようにformatLocalized()メソッドを使った方法が多く出てきますが、Carbon 2では isoFormat()メソッドが推奨されています。
$dt = new Carbon(); echo $dt-&amp;gt;isoFormat(&amp;#39;YYYY年MM月DD日（ddd）&amp;#39;); </description>
            <content type="html"><![CDATA[<p>Carbonで曜日を表示する方法を調べてみると、</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$dt <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Carbon</span>();
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> $dt<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">formatLocalized</span>(<span style="color:#e6db74">&#39;%Y年%m月%d日（%a）&#39;</span>);
</span></span></code></pre></div><p>のように<code>formatLocalized()</code>メソッドを使った方法が多く出てきますが、Carbon 2では <code>isoFormat()</code>メソッドが推奨されています。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$dt <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">Carbon</span>();
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> $dt<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">isoFormat</span>(<span style="color:#e6db74">&#39;YYYY年MM月DD日（ddd）&#39;</span>);
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>LaravelのFormRequestでAjaxに対応させる</title>
            <link>https://eza-s.com/blog/archives/379/</link>
            <pubDate>Mon, 25 Nov 2019 05:42:25 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/379/</guid>
            <description>確認に使ったLaravelのバージョンは5.8です。
Laravelのフォームリクエストを使うと、記述したルールでのバリデーションを使ってバリデーションを行い、エラーがあった場合はエラー内容を持って前の画面に戻る、というのを行ってくれます。
コントローラー内に処理を書かなくて良くなり、コントローラーが見やすくなるので、APIの実装にも使いたいけどエラー内容をjsonで返すのどうやるんだろ？ていうときの書き方です。
protected function failedValidation(Validator $validator) { if (request()-&amp;gt;expectsJson()) { $response[&amp;#39;errors&amp;#39;] = $validator-&amp;gt;errors()-&amp;gt;toArray(); throw new HttpResponseException( response()-&amp;gt;json( $response, 422 ) ); } } フォームリクエストクラス内に上記メソッドを追加します。
最初のif文でAjaxリクエストかどうか判定しています。Ajaxリクエストじゃない場合は何もせず通常通りとなりますので、Ajax、htmlのformどちらからのリクエストにも対応しています。
参考
https://qiita.com/yamatox/items/94e123849d924329a167</description>
            <content type="html"><![CDATA[<p>確認に使ったLaravelのバージョンは5.8です。</p>
<p>Laravelのフォームリクエストを使うと、記述したルールでのバリデーションを使ってバリデーションを行い、エラーがあった場合はエラー内容を持って前の画面に戻る、というのを行ってくれます。<br>
コントローラー内に処理を書かなくて良くなり、コントローラーが見やすくなるので、APIの実装にも使いたいけどエラー内容をjsonで返すのどうやるんだろ？ていうときの書き方です。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">protected</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">failedValidation</span>(<span style="color:#a6e22e">Validator</span> $validator)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">request</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">expectsJson</span>()) {
</span></span><span style="display:flex;"><span>        $response[<span style="color:#e6db74">&#39;errors&#39;</span>]  <span style="color:#f92672">=</span> $validator<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">errors</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">toArray</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">throw</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">HttpResponseException</span>(
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">response</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">json</span>( $response, <span style="color:#ae81ff">422</span> )
</span></span><span style="display:flex;"><span>        );
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>フォームリクエストクラス内に上記メソッドを追加します。<br>
最初のif文でAjaxリクエストかどうか判定しています。Ajaxリクエストじゃない場合は何もせず通常通りとなりますので、Ajax、htmlのformどちらからのリクエストにも対応しています。</p>
<p>参考<br>
<a href="https://qiita.com/yamatox/items/94e123849d924329a167">https://qiita.com/yamatox/items/94e123849d924329a167</a></p>
]]></content>
        </item>
        
        <item>
            <title>GitHubで2段階認証を設定した後のpushやcloneがエラーになる</title>
            <link>https://eza-s.com/blog/archives/371/</link>
            <pubDate>Sun, 01 Sep 2019 05:03:12 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/371/</guid>
            <description>GitHubで2段階認証を設定した後、それまで使っていたリポジトリへのpushがエラーで出来なくなりました。
https://wada811.blogspot.com/2014/05/failed-to-push-to-github-over-https.html
https://qiita.com/kz800/items/497ec70bff3e555dacd0
を参考に、GitHubのPersonal access tokensを設定して .netrcに記述すればpushは出来るようになりました。
その後、別のプライベートリポジトリをcloneしようとしたらエラーで出来なかったので、以下のようにすればclone出来ました。
git clone https://ユーザ名:アクセストークン@github.com/ユーザ名/リポジトリ名 </description>
            <content type="html"><![CDATA[<p>GitHubで2段階認証を設定した後、それまで使っていたリポジトリへのpushがエラーで出来なくなりました。</p>
<p><a href="https://wada811.blogspot.com/2014/05/failed-to-push-to-github-over-https.html">https://wada811.blogspot.com/2014/05/failed-to-push-to-github-over-https.html</a><br>
<a href="https://qiita.com/kz800/items/497ec70bff3e555dacd0">https://qiita.com/kz800/items/497ec70bff3e555dacd0</a><br>
を参考に、GitHubのPersonal access tokensを設定して .netrcに記述すればpushは出来るようになりました。</p>
<p>その後、別のプライベートリポジトリをcloneしようとしたらエラーで出来なかったので、以下のようにすればclone出来ました。</p>
<pre tabindex="0"><code>git clone https://ユーザ名:アクセストークン@github.com/ユーザ名/リポジトリ名
</code></pre>]]></content>
        </item>
        
        <item>
            <title>Laravel本番環境構築メモ</title>
            <link>https://eza-s.com/blog/archives/362/</link>
            <pubDate>Fri, 09 Aug 2019 05:42:50 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/362/</guid>
            <description>CentOS7 + Nginx + PHP + PostgreSQL + Redis + Supervisorで本番環境を構築した時の作業履歴。
さくらのクラウドを使いました。
初期設定 今回に限らず、サーバ構築時の共通設定として以下の作業を行いました。
一般ユーザーの作成&amp;amp;sudo&amp;amp;ssh接続設定（公開鍵認証）&amp;amp;システムアップデート 参考: https://help.sakura.ad.jp/hc/ja/articles/206208181
sshdの再起動は
# systemctl restart sshd 参考URLにあるパケットフィルターはさくらのVPS用のものなので、ここではスルーします。
yum-cronによるパッケージの自動更新 インストール # yum -y install yum-cron 設定 # vi /etc/yum/yum-cron.conf 自動更新を有効に設定
apply_updates = yes サービス起動&amp;amp;自動起動設定 # systemctl start yum-cron # systemctl enable yum-cron # systemctl enable yum-cron Firewall設定 http、httpsのポートを開けます。
# vi /etc/firewalld/zones/public.xml &amp;lt;zone&amp;gt; …省略 &amp;lt;service name=&amp;#34;http&amp;#34;/&amp;gt; &amp;lt;service name=&amp;#34;https&amp;#34;/&amp;gt; &amp;lt;/zone&amp;gt; 設定変更したらサービスを再起動します。
# systemctl restart firewalld Nginx インストール # vi /etc/yum.</description>
            <content type="html"><![CDATA[<p>CentOS7 + Nginx + PHP + PostgreSQL + Redis + Supervisorで本番環境を構築した時の作業履歴。<br>
さくらのクラウドを使いました。</p>
<h2 id="初期設定">初期設定</h2>
<p>今回に限らず、サーバ構築時の共通設定として以下の作業を行いました。</p>
<h3 id="一般ユーザーの作成sudossh接続設定公開鍵認証システムアップデート">一般ユーザーの作成&amp;sudo&amp;ssh接続設定（公開鍵認証）&amp;システムアップデート</h3>
<p>参考: <a href="https://help.sakura.ad.jp/hc/ja/articles/206208181">https://help.sakura.ad.jp/hc/ja/articles/206208181</a></p>
<p>sshdの再起動は</p>
<pre tabindex="0"><code># systemctl restart sshd
</code></pre><p>参考URLにあるパケットフィルターはさくらのVPS用のものなので、ここではスルーします。</p>
<h3 id="yum-cronによるパッケージの自動更新">yum-cronによるパッケージの自動更新</h3>
<h4 id="インストール">インストール</h4>
<pre tabindex="0"><code># yum -y install yum-cron
</code></pre><h4 id="設定">設定</h4>
<pre tabindex="0"><code># vi /etc/yum/yum-cron.conf
</code></pre><p>自動更新を有効に設定</p>
<pre tabindex="0"><code>apply_updates = yes
</code></pre><h4 id="サービス起動自動起動設定">サービス起動&amp;自動起動設定</h4>
<pre tabindex="0"><code># systemctl start yum-cron # systemctl enable yum-cron
# systemctl enable yum-cron
</code></pre><h3 id="firewall設定">Firewall設定</h3>
<p>http、httpsのポートを開けます。</p>
<pre tabindex="0"><code># vi /etc/firewalld/zones/public.xml
</code></pre><pre tabindex="0"><code>&lt;zone&gt;
  …省略
  &lt;service name=&#34;http&#34;/&gt;
  &lt;service name=&#34;https&#34;/&gt;
&lt;/zone&gt;
</code></pre><p>設定変更したらサービスを再起動します。</p>
<pre tabindex="0"><code># systemctl restart firewalld
</code></pre><h2 id="nginx">Nginx</h2>
<h3 id="インストール-1">インストール</h3>
<pre tabindex="0"><code># vi /etc/yum.repos.d/nginx.repo
</code></pre><pre tabindex="0"><code>[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
enabled=0
gpgcheck=0
</code></pre><pre tabindex="0"><code>yum -y --enablerepo=nginx install nginx
</code></pre><h3 id="サービス起動自動起動設定-1">サービス起動&amp;自動起動設定</h3>
<pre tabindex="0"><code># systemctl start nginx
# systemctl enable nginx
</code></pre><h2 id="phpphp-fpm">php&amp;php-fpm</h2>
<h3 id="epelリポジトリの追加">EPELリポジトリの追加</h3>
<pre tabindex="0"><code># yum install epel-release
</code></pre><p>インストール済みだったような。</p>
<h3 id="remiリポジトリの追加">remiリポジトリの追加</h3>
<pre tabindex="0"><code># rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
</code></pre><h3 id="インストール-2">インストール</h3>
<pre tabindex="0"><code>$ sudo yum -y install --enablerepo=remi,remi-php73 php php-devel php-mbstring php-pdo php-pgsql php-gd php-xml php-mcrypt php-fpm
</code></pre><h3 id="php-fpmの設定">php-fpmの設定</h3>
<pre tabindex="0"><code># vi /etc/php-fpm.d/www.conf
</code></pre><pre tabindex="0"><code>user = nginx
group = nginx
listen = /var/run/php-fpm/php-fpm.sock;
listen.owner = nginx
listen.group = nginx
</code></pre><h3 id="php-fpm起動自動起動設定">php-fpm起動&amp;自動起動設定</h3>
<pre tabindex="0"><code># systemctl start php-fpm
# systemctl enable php-fpm
</code></pre><h3 id="nginxでphpを設定">Nginxでphpを設定</h3>
<pre tabindex="0"><code># vi /etc/nginx/conf.d/default.conf
</code></pre><pre tabindex="0"><code>root   /usr/share/nginx/html;
</code></pre><p>location / {} の中からserver {} 直下に出す</p>
<pre tabindex="0"><code>location / {
    index index.php index.html index.htm;
}
</code></pre><p>index.phpを追加</p>
<pre tabindex="0"><code>location ~ \.php$ {
    #root           html;
    fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
    include        fastcgi_params;
}
</code></pre><p>コメントを外して、それぞれ変更</p>
<h3 id="動作確認用phpファイル作成">動作確認用phpファイル作成</h3>
<pre tabindex="0"><code># vi /usr/share/nginx/html/phpinfo.php
</code></pre><pre tabindex="0"><code>&lt;?php phpinfo(); ?&gt;
</code></pre><h3 id="nginxを再起動">Nginxを再起動</h3>
<pre tabindex="0"><code># systemctl restart nginx
</code></pre><p>ブラウザから /phpinfo.php にアクセスして表示されるのを確認</p>
<h3 id="composerインストール">Composerインストール</h3>
<pre tabindex="0"><code>$ php -r &#34;copy(&#39;https://getcomposer.org/installer&#39;, &#39;composer-setup.php&#39;);&#34;
$ php -r &#34;if (hash_file(&#39;sha384&#39;, &#39;composer-setup.php&#39;) === &#39;48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5&#39;) { echo &#39;Installer verified&#39;; } else { echo &#39;Installer corrupt&#39;; unlink(&#39;composer-setup.php&#39;); } echo PHP_EOL;&#34;
$ php composer-setup.php
$ php -r &#34;unlink(&#39;composer-setup.php&#39;);&#34;

$ sudo mv composer.phar /usr/local/bin/composer
</code></pre><h2 id="postgresql">PostgreSQL</h2>
<h3 id="インストール-3">インストール</h3>
<pre tabindex="0"><code># yum -y install postgresql-server postgresql-devel
</code></pre><h3 id="初期化処理">初期化処理</h3>
<pre tabindex="0"><code># postgresql-setup initdb
</code></pre><h3 id="サービス起動自動起動設定-2">サービス起動&amp;自動起動設定</h3>
<pre tabindex="0"><code># systemctl start postgresql.service
# systemctl enable postgresql.service
</code></pre><h3 id="パスワード認証に変更">パスワード認証に変更</h3>
<pre tabindex="0"><code># vi /var/lib/pgsql/data/pg_hba.conf
</code></pre><pre tabindex="0"><code>local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5
</code></pre><p>に変更</p>
<h3 id="postgresユーザのdb接続パスワード設定">postgresユーザのDB接続パスワード設定</h3>
<pre tabindex="0"><code># su - postgres
$ psql -U postgres
postgres=# ALTER USER postgres encrypted password &#39;パスワード&#39;; postgres=# \q
$ exit
</code></pre><h3 id="サービス再起動">サービス再起動</h3>
<pre tabindex="0"><code># systemctl restart postgresql.service
</code></pre><h3 id="ユーザー作成">ユーザー作成</h3>
<pre tabindex="0"><code># su - postgres
$ createuser -P ユーザー名
パスワード入力
</code></pre><h3 id="db作成">DB作成</h3>
<pre tabindex="0"><code>$ psql -U postgres
postgres=# create database DB名 owner ユーザー名;
</code></pre><h2 id="redis">Redis</h2>
<h3 id="インストール-4">インストール</h3>
<pre tabindex="0"><code># yum install --enablerepo=epel,remi redis
</code></pre><h3 id="サービス起動自動起動設定-3">サービス起動&amp;自動起動設定</h3>
<pre tabindex="0"><code># systemctl start redis.service
# systemctl enable redis.service
</code></pre><h2 id="laravelアプリ">Laravelアプリ</h2>
<p>Laravelアプリのgitリポジトリがある前提です。<br>
今回は /var/www ディレクトリに配置します。上記で作成した一般ユーザが書き込みできるよう権限を付加しておきます。</p>
<h3 id="git-clone">git clone</h3>
<pre tabindex="0"><code>$ git clone リポジトリURL
$ cd リポジトリ名
</code></pre><h3 id="laravelセットアップ">Laravelセットアップ</h3>
<pre tabindex="0"><code>$ composer install
$ cp .env.example .env
$ php artisan key:generate
$ vi .env
</code></pre><pre tabindex="0"><code>APP_ENV=production
APP_DEBUG=false
APP_URL=[LaravelアプリのURL]

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=[作成したDB名]
DB_USERNAME=[作成したDBユーザ名]
DB_PASSWORD=[DBユーザのパスワード]

QUEUE_CONNECTION=redis

MAIL_DRIVER=sparkpost
SPARKPOST_SECRET=[sparkpostのAPIキー]
</code></pre><p>メール送信は <a href="https://www.sparkpost.com/">https://www.sparkpost.com/</a> を利用しました。</p>
<pre tabindex="0"><code>$ php artisan migrate:fresh --seed
$ chmod 777 -R /var/www/imbr-delivery/storage
</code></pre><h3 id="nginx設定変更">Nginx設定変更</h3>
<pre tabindex="0"><code># vi /etc/nginx/conf.d/default.conf
</code></pre><pre tabindex="0"><code>root   /var/www/[リポジトリ名]/public;

location / {
    index  index.php index.html index.htm;
    try_files $uri $uri/ /index.php?$query_string;
}
</code></pre><p>設定変更後、サービスを再起動する。</p>
<pre tabindex="0"><code># systemctl restart nginx
</code></pre><h2 id="lets-encript">Let&rsquo;s Encript</h2>
<h3 id="certbotのインストール">certbotのインストール</h3>
<p>一般ユーザのホームディレクトリで行いました。</p>
<pre tabindex="0"><code>$ git clone https://github.com/certbot/certbot
</code></pre><h3 id="証明書の取得">証明書の取得</h3>
<pre tabindex="0"><code>$ cd certbot
$ sudo ./certbot-auto --nginx
</code></pre><h3 id="証明書の更新">証明書の更新</h3>
<pre tabindex="0"><code>0 4 1 * * /home/[一般ユーザ名]/certbot/certbot-auto renew &amp;&amp; /bin/systemctl reload nginx
</code></pre><p>cronで設定します。</p>
<h2 id="supervisor">Supervisor</h2>
<h3 id="インストール-5">インストール</h3>
<pre tabindex="0"><code># yum install supervisor
</code></pre><h3 id="サービス起動自動起動設定-4">サービス起動&amp;自動起動設定</h3>
<pre tabindex="0"><code># systemctl start supervisord.service
# systemctl status supervisord.service
</code></pre><h3 id="設定ファイル編集">設定ファイル編集</h3>
<pre tabindex="0"><code># vi /etc/supervisord.d/laravel-worker.ini
</code></pre><pre tabindex="0"><code>[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
directory=/var/www/[リポジトリ名]
command=php artisan queue:work redis --sleep=3 --tries=1
autostart=true
autorestart=true
user=root
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/imbr-delivery/storage/logs/worker.log
</code></pre><h3 id="supervisorの起動">supervisorの起動</h3>
<pre tabindex="0"><code># supervisorctl reread
# supervisorctl update
# supervisorctl start laravel-worker:*
</code></pre><h2 id="その他">その他</h2>
<h3 id="タスクスケジューラ">タスクスケジューラ</h3>
<p>Laravelのタスクスケジューラを使うために以下のCron設定を行います。</p>
<pre tabindex="0"><code>0,10,20,30,40,50 * * * * cd /var/www/[リポジトリ名] &amp;&amp; php artisan schedule:run &gt;&gt; /dev/null 2&gt;&amp;1
</code></pre>]]></content>
        </item>
        
        <item>
            <title>Laravelでアップロードしたファイルがジョブから参照できない</title>
            <link>https://eza-s.com/blog/archives/356/</link>
            <pubDate>Tue, 02 Jul 2019 02:51:02 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/356/</guid>
            <description>はじめに 管理画面で何かしらのデータをCSVファイルのアップロードによってインポートする機能を作りました。データの件数によっては処理に時間がかかってしまうので、インポート処理はジョブ化して非同期で実行するようにしました。
use App\Http\Requests\CsvRequest; use App\Jobs\ImportFromCsvJob; class ImportController extends Controller { public function importCsv(CsvRequest $request) { $path = $request-&amp;gt;csv-&amp;gt;store(&amp;#39;csv&amp;#39;); ImportFromCsvJob::dispatch(auth()-&amp;gt;user(), $path); $request-&amp;gt;session()-&amp;gt;flash(&amp;#39;success&amp;#39;, &amp;#39;作成処理を開始しました。終了したらメールで通知します。&amp;#39;); return back(); } } このように、コントローラー側でアップロードされたファイルを保存して、そのパスをジョブに渡します。ジョブ側では受け取ったパスをStorage::get()で読み込んでインポート処理を行います。
ローカル環境で確認して問題なかったので検証用環境にデプロイしたのですがインポートされませんでした。調べてみると、ジョブ側で File not found となっていました。
検証用環境 検証用環境はDokkuというHerokuライクなツールで構築しています。詳しい設定内容は省略しますが、Procfileにて
web: vendor/bin/heroku-php-apache2 public/ worker: php artisan queue:work --tries=3 となっていて、管理画面とキューワーカがそれぞれ実行されています。
原因と対応 管理画面とキューワーカはそれぞれ別のコンテナとなります。なのでwebにアップロードしたファイルがworkerには存在しませんでした。
# 検証用環境にて $ dokku enter app-name web # webコンテナに入る $ ls storage/app アップロードしたファイルが表示される $ exit $ dokku enter app-name worker # workerコンテナに入る $ ls storage/app アップロードしたファイルは表示されない $ exit ストレージプラグインを使ってコンテナ間で共有できるストレージを設定しました。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>管理画面で何かしらのデータをCSVファイルのアップロードによってインポートする機能を作りました。データの件数によっては処理に時間がかかってしまうので、インポート処理はジョブ化して非同期で実行するようにしました。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">App\Http\Requests\CsvRequest</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">App\Jobs\ImportFromCsvJob</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ImportController</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Controller</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">importCsv</span>(<span style="color:#a6e22e">CsvRequest</span> $request)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        $path <span style="color:#f92672">=</span> $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">csv</span><span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">store</span>(<span style="color:#e6db74">&#39;csv&#39;</span>);
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">ImportFromCsvJob</span><span style="color:#f92672">::</span><span style="color:#a6e22e">dispatch</span>(<span style="color:#a6e22e">auth</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">user</span>(), $path);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">session</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">flash</span>(<span style="color:#e6db74">&#39;success&#39;</span>, <span style="color:#e6db74">&#39;作成処理を開始しました。終了したらメールで通知します。&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">back</span>();
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>このように、コントローラー側でアップロードされたファイルを保存して、そのパスをジョブに渡します。ジョブ側では受け取ったパスを<code>Storage::get()</code>で読み込んでインポート処理を行います。</p>
<p>ローカル環境で確認して問題なかったので検証用環境にデプロイしたのですがインポートされませんでした。調べてみると、ジョブ側で File not found となっていました。</p>
<h2 id="検証用環境">検証用環境</h2>
<p>検証用環境は<a href="http://dokku.viewdocs.io/dokku/">Dokku</a>というHerokuライクなツールで構築しています。詳しい設定内容は省略しますが、Procfileにて</p>
<pre tabindex="0"><code>web: vendor/bin/heroku-php-apache2 public/
worker: php artisan queue:work --tries=3
</code></pre><p>となっていて、管理画面とキューワーカがそれぞれ実行されています。</p>
<h2 id="原因と対応">原因と対応</h2>
<p>管理画面とキューワーカはそれぞれ別のコンテナとなります。なのでwebにアップロードしたファイルがworkerには存在しませんでした。</p>
<pre tabindex="0"><code># 検証用環境にて
$ dokku enter app-name web # webコンテナに入る
$ ls storage/app
アップロードしたファイルが表示される
$ exit
$ dokku enter app-name worker # workerコンテナに入る
$ ls storage/app
アップロードしたファイルは表示されない
$ exit
</code></pre><p>ストレージプラグインを使ってコンテナ間で共有できるストレージを設定しました。</p>
<pre tabindex="0"><code>$ dokku storage:mount app-name /path/to/shared-storage:/app/storage/app
$ dokku ps:rebuild app-name
</code></pre><p>これでインポート処理が行われるのを確認しました。</p>
<p>Laravelで、と書きましたがLaravel関係なかったです。仮想環境での問題なので、Herokuでも同様の対応が必要になると思われます。</p>
]]></content>
        </item>
        
        <item>
            <title>LaravelでシンプルなトークンベースのAPI認証を行う</title>
            <link>https://eza-s.com/blog/archives/327/</link>
            <pubDate>Tue, 30 Apr 2019 10:20:47 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/327/</guid>
            <description>はじめに config/auth.php にデフォルトで設定されている guards.api を使用してAPI認証を行うために必要な項目についてまとめました。
ベースとなる認証については php artisan make:auth で作成している前提となります。Laravel5.7で確認しました。
カラム追加 users テーブルにトークンを保持するための api_token カラムを追加します。
$ php artisan make:migration add_api_token_to_users_table --table=users &amp;lt;?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class AddApiTokenToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::table(&amp;#39;users&amp;#39;, function (Blueprint $table) { $table-&amp;gt;string(&amp;#39;api_token&amp;#39;, 60)-&amp;gt;unique()-&amp;gt;nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table(&amp;#39;users&amp;#39;, function (Blueprint $table) { $table-&amp;gt;dropColumn(&amp;#39;api_token&amp;#39;); }); } } $ php artisan migrate モデル変更 App\Userの $fillable と $hidden に api_token を追加します。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p><code>config/auth.php</code> にデフォルトで設定されている <code>guards.api</code> を使用してAPI認証を行うために必要な項目についてまとめました。<br>
ベースとなる認証については <code>php artisan make:auth</code> で作成している前提となります。Laravel5.7で確認しました。</p>
<h2 id="カラム追加">カラム追加</h2>
<p>users テーブルにトークンを保持するための api_token カラムを追加します。</p>
<pre tabindex="0"><code>$ php artisan make:migration add_api_token_to_users_table --table=users
</code></pre><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Support\Facades\Schema</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Database\Schema\Blueprint</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Database\Migrations\Migration</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AddApiTokenToUsersTable</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Migration</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Run the migrations.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return void
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">up</span>()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">Schema</span><span style="color:#f92672">::</span><span style="color:#a6e22e">table</span>(<span style="color:#e6db74">&#39;users&#39;</span>, <span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">Blueprint</span> $table) {
</span></span><span style="display:flex;"><span>            $table<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">string</span>(<span style="color:#e6db74">&#39;api_token&#39;</span>, <span style="color:#ae81ff">60</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">unique</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">nullable</span>();
</span></span><span style="display:flex;"><span>        });
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Reverse the migrations.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return void
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">down</span>()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">Schema</span><span style="color:#f92672">::</span><span style="color:#a6e22e">table</span>(<span style="color:#e6db74">&#39;users&#39;</span>, <span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">Blueprint</span> $table) {
</span></span><span style="display:flex;"><span>            $table<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">dropColumn</span>(<span style="color:#e6db74">&#39;api_token&#39;</span>);
</span></span><span style="display:flex;"><span>        });
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><pre tabindex="0"><code>$ php artisan migrate
</code></pre><h2 id="モデル変更">モデル変更</h2>
<p><code>App\User</code>の $fillable と $hidden に api_token を追加します。</p>
<h2 id="トークンの作成削除">トークンの作成・削除</h2>
<p>ログイン時にトークンを生成、ログアウト時にトークンを削除する処理を入れます。<br>
<code>app/Http/Controllers/Auth/LoginController.php</code>に以下を追加します。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Support\Str</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">LoginController</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Controller</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">protected</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">authenticated</span>(<span style="color:#a6e22e">Request</span> $request, $user)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        $user<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">update</span>([<span style="color:#e6db74">&#39;api_token&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">Str</span><span style="color:#f92672">::</span><span style="color:#a6e22e">random</span>(<span style="color:#ae81ff">60</span>)]);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">logout</span>(<span style="color:#a6e22e">Request</span> $request)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        $user <span style="color:#f92672">=</span> $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">user</span>();
</span></span><span style="display:flex;"><span>        $user<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">update</span>([<span style="color:#e6db74">&#39;api_token&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#66d9ef">null</span>]);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">guard</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">logout</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">session</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">invalidate</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">loggedOut</span>($request) <span style="color:#f92672">?:</span> <span style="color:#a6e22e">redirect</span>(<span style="color:#e6db74">&#39;/&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="動作確認">動作確認</h2>
<p><code>routes/api.php</code>にデフォルトで定義されている以下のルーティングで確認します。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">middleware</span>(<span style="color:#e6db74">&#39;auth:api&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;/user&#39;</span>, <span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">Request</span> $request) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">user</span>();
</span></span><span style="display:flex;"><span>});
</span></span></code></pre></div><p>webから任意のユーザでログインし、トークンを生成します。生成したトークンはGETパラメータ api_token で渡すか、Headerパラメータの <code>Authorization: Bearer トークン</code>で渡すことができます。<br>
/api/user にアクセスしてログインしているユーザの情報がjsonで取得できれば成功です。</p>
<p>認証に失敗した場合、Headerパラメータの Accept: application/json または X-Requested-With: XMLHttpRequest が設定されている場合は “message”: “Unauthenticated.” のjsonレスポンスが、それ以外はログイン画面に遷移するようになっています。</p>
<h2 id="参考">参考</h2>
<p><a href="https://qiita.com/zaburo/items/57657c78f54accf400f6">https://qiita.com/zaburo/items/57657c78f54accf400f6</a><br>
<a href="https://www.webopixel.net/php/1343.html">https://www.webopixel.net/php/1343.html</a><br>
<a href="https://readouble.com/laravel/5.8/ja/api-authentication.html">https://readouble.com/laravel/5.8/ja/api-authentication.html</a></p>
]]></content>
        </item>
        
        <item>
            <title>Laravelのフォームリクエストバリデーションでuniqueの除外IDが効かない</title>
            <link>https://eza-s.com/blog/archives/320/</link>
            <pubDate>Sat, 06 Apr 2019 03:38:12 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/320/</guid>
            <description>フォームリクエストバリデーションでuniqueの除外IDを指定する方法はこちら
実装しているとたまに表題の現象が発生して、見た感じパラメータも間違ってないのになんでだろう？ってなることがあったのでメモ。
結論を先に書くと、ルートパラメータとinputパラメータのパラメータ名が重複しているのが原因でした。
例えばIPアドレスを管理するとして、ip_addressesテーブルにip_addressカラムがあるとします。（その他のカラムは省略）
これを Route::resource(‘ip_addresses’, ‘IpAddressController’) なルーティングにした場合、フォームリクエストバリデーションでuniqueの除外IDに指定するパラメータ $this-&amp;gt;ip_addressに入っているのはルートパラメータではなく、フォームのip_addressの入力値となります。（上記リンク参照）
解決策としては、ルーティングを以下のように変更してルートパラメータ名を変更する方法があります。
Route::resource(&amp;#39;ip_addresses&amp;#39;, &amp;#39;IpAddressController&amp;#39;)-&amp;gt;parameters([ &amp;#39;ip_addresses&amp;#39; =&amp;gt; &amp;#39;ipAddress&amp;#39;, ]); これでフォームリクエストバリデーションでuniqueの除外IDに指定するパラメータを $this-&amp;gt;ipAddress にすれば有効になります。</description>
            <content type="html"><![CDATA[<p>フォームリクエストバリデーションでuniqueの除外IDを指定する方法は<a href="https://eza-s.com/blog/archives/73">こちら</a></p>
<p>実装しているとたまに表題の現象が発生して、見た感じパラメータも間違ってないのになんでだろう？ってなることがあったのでメモ。</p>
<p>結論を先に書くと、ルートパラメータとinputパラメータのパラメータ名が重複しているのが原因でした。</p>
<p>例えばIPアドレスを管理するとして、ip_addressesテーブルにip_addressカラムがあるとします。（その他のカラムは省略）<br>
これを Route::resource(‘ip_addresses’, ‘IpAddressController’) なルーティングにした場合、フォームリクエストバリデーションでuniqueの除外IDに指定するパラメータ $this-&gt;ip_addressに入っているのはルートパラメータではなく、フォームのip_addressの入力値となります。（上記リンク参照）</p>
<p>解決策としては、ルーティングを以下のように変更してルートパラメータ名を変更する方法があります。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">resource</span>(<span style="color:#e6db74">&#39;ip_addresses&#39;</span>, <span style="color:#e6db74">&#39;IpAddressController&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">parameters</span>([
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;ip_addresses&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;ipAddress&#39;</span>,
</span></span><span style="display:flex;"><span>]);
</span></span></code></pre></div><p>これでフォームリクエストバリデーションでuniqueの除外IDに指定するパラメータを $this-&gt;ipAddress にすれば有効になります。</p>
]]></content>
        </item>
        
        <item>
            <title>LaravelのNotificationが Call to a member function routeNotificationFor() on null</title>
            <link>https://eza-s.com/blog/archives/315/</link>
            <pubDate>Fri, 22 Feb 2019 08:14:47 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/315/</guid>
            <description>管理画面系で時間がかかりそうな処理をJobに切り出して、そのJobの中ですべての処理が終わったらログインしているユーザに通知メールを送信しようと以下のようなコードを書きました。
Notification::send(auth()-&amp;gt;user(), new NotificationClassName()); ローカル環境ではキューの設定(QUEUE_CONNECTION)がジョブが即時に実行される設定(sync)になっていて、それだと動いたのにデータベース(database)に変更したら動きませんでした。Laravelのログを確認したら
Call to a member function routeNotificationFor() on null の文字が。キューがバックエンドで実行される事になって auth() が取得できなくなったという、当たり前といえば当たり前な出来事でした。
ログインユーザのインスタンスを別途受け渡して解決しました。確認したLaravelのバージョンは5.7です。</description>
            <content type="html"><![CDATA[<p>管理画面系で時間がかかりそうな処理をJobに切り出して、そのJobの中ですべての処理が終わったらログインしているユーザに通知メールを送信しようと以下のようなコードを書きました。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">Notification</span><span style="color:#f92672">::</span><span style="color:#a6e22e">send</span>(<span style="color:#a6e22e">auth</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">user</span>(), <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">NotificationClassName</span>());
</span></span></code></pre></div><p>ローカル環境ではキューの設定(QUEUE_CONNECTION)がジョブが即時に実行される設定(sync)になっていて、それだと動いたのにデータベース(database)に変更したら動きませんでした。Laravelのログを確認したら</p>
<pre tabindex="0"><code>Call to a member function routeNotificationFor() on null
</code></pre><p>の文字が。キューがバックエンドで実行される事になって auth() が取得できなくなったという、当たり前といえば当たり前な出来事でした。<br>
ログインユーザのインスタンスを別途受け渡して解決しました。確認したLaravelのバージョンは5.7です。</p>
]]></content>
        </item>
        
        <item>
            <title>Laravelのバリデーションで登録時と編集時でルールを変更したい</title>
            <link>https://eza-s.com/blog/archives/305/</link>
            <pubDate>Sun, 13 Jan 2019 09:29:07 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/305/</guid>
            <description>例えばユーザのパスワードなんかで登録時は必須だけど、編集のときは未入力だとパスワード変更なし、入力があれば変更する、というパターンがあると思います。登録と編集で別々にバリデーションを用意するのも冗長だしresource単位でまとめておきたい、そんな場合の書き方です。確認したバージョンはLaravel5.7です。
public function rules() { return [ &amp;#39;name&amp;#39; =&amp;gt; &amp;#39;required|max:255&amp;#39;, &amp;#39;email&amp;#39; =&amp;gt; [ &amp;#39;required&amp;#39;, &amp;#39;max:255&amp;#39;, &amp;#39;email&amp;#39;, Rule::unique(&amp;#39;users&amp;#39;)-&amp;gt;ignore($this-&amp;gt;user), ], &amp;#39;password&amp;#39; =&amp;gt; ($this-&amp;gt;user) ? &amp;#39;nullable|min:6|confirmed&amp;#39; : &amp;#39;required|min:6|confirmed&amp;#39;, ]; } ↑はFormRequestに定義するrulesになります。ルーティングは↓を想定しています。
Route::resource(&amp;#39;users&amp;#39;, &amp;#39;UserController&amp;#39;); また、コントローラー側でデータを保存前にpasswordの入力があるかチェックをして、入力がなければパラメータに含めない、という制御も必要になります。
public function update(UserRequest $request, User $user) { $validatedData = $request-&amp;gt;validated(); if ($validatedData[&amp;#39;password&amp;#39;]) { $validatedData[&amp;#39;password&amp;#39;] = Hash::make($validatedData[&amp;#39;password&amp;#39;]); } else { unset($validatedData[&amp;#39;password&amp;#39;]); } $user-&amp;gt;update($validatedData); return redirect()-&amp;gt;route(&amp;#39;users.show&amp;#39;, [$user]); } </description>
            <content type="html"><![CDATA[<p>例えばユーザのパスワードなんかで登録時は必須だけど、編集のときは未入力だとパスワード変更なし、入力があれば変更する、というパターンがあると思います。登録と編集で別々にバリデーションを用意するのも冗長だしresource単位でまとめておきたい、そんな場合の書き方です。確認したバージョンはLaravel5.7です。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">rules</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;name&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;required|max:255&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;email&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;required&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;max:255&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;email&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">Rule</span><span style="color:#f92672">::</span><span style="color:#a6e22e">unique</span>(<span style="color:#e6db74">&#39;users&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">ignore</span>($this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">user</span>),
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;password&#39;</span> <span style="color:#f92672">=&gt;</span> ($this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">user</span>) <span style="color:#f92672">?</span> <span style="color:#e6db74">&#39;nullable|min:6|confirmed&#39;</span> <span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;required|min:6|confirmed&#39;</span>,
</span></span><span style="display:flex;"><span>    ];
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>↑はFormRequestに定義するrulesになります。ルーティングは↓を想定しています。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">resource</span>(<span style="color:#e6db74">&#39;users&#39;</span>, <span style="color:#e6db74">&#39;UserController&#39;</span>);
</span></span></code></pre></div><p>また、コントローラー側でデータを保存前にpasswordの入力があるかチェックをして、入力がなければパラメータに含めない、という制御も必要になります。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">update</span>(<span style="color:#a6e22e">UserRequest</span> $request, <span style="color:#a6e22e">User</span> $user)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $validatedData <span style="color:#f92672">=</span> $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">validated</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($validatedData[<span style="color:#e6db74">&#39;password&#39;</span>]) {
</span></span><span style="display:flex;"><span>        $validatedData[<span style="color:#e6db74">&#39;password&#39;</span>] <span style="color:#f92672">=</span> <span style="color:#a6e22e">Hash</span><span style="color:#f92672">::</span><span style="color:#a6e22e">make</span>($validatedData[<span style="color:#e6db74">&#39;password&#39;</span>]);
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">unset</span>($validatedData[<span style="color:#e6db74">&#39;password&#39;</span>]);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    $user<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">update</span>($validatedData);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">redirect</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">route</span>(<span style="color:#e6db74">&#39;users.show&#39;</span>, [$user]);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>Laravelのミドルウェアでセッションを使う</title>
            <link>https://eza-s.com/blog/archives/293/</link>
            <pubDate>Fri, 12 Oct 2018 05:07:54 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/293/</guid>
            <description>はじめに 今回やりたいことは、ページの日本語／英語の表示切り替えで、設定内容をセッションで保持してページの読み込み時にセッションに保持された設定があれば反映する、ということです。
コントローラのコンストラクタに書けばいいかと思い調べてみたら、Laravel5.3以降は普通に書いても動かなくなったということで（参考ページ）回避策として下のような書き方が使えるということがわかりました。
public function __construct() { $this-&amp;gt;middleware(function ($request, $next) { if (session(&amp;#39;lang&amp;#39;)) { \App::setLocale(session(&amp;#39;lang&amp;#39;)); } return $next($request); }); } ですがせっかくなのでミドルウェアを定義してみようと思います。Laravelのバージョンは5.7です。
実装 ミドルウェア作成 $ php artisan make:middleware Lang &amp;lt;?php namespace App\Http\Middleware; use Closure; class Lang { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if (session(&amp;#39;lang&amp;#39;)) { \App::setLocale(session(&amp;#39;lang&amp;#39;)); } return $next($request); } } ミドルウェア登録 app/Http/Kernel.</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>今回やりたいことは、ページの日本語／英語の表示切り替えで、設定内容をセッションで保持してページの読み込み時にセッションに保持された設定があれば反映する、ということです。</p>
<p>コントローラのコンストラクタに書けばいいかと思い調べてみたら、Laravel5.3以降は普通に書いても動かなくなったということで（<a href="https://www.larajapan.com/2016/09/24/laravel-5-3%E3%80%80%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9%E3%81%AE%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%AE%E9%87%8D%E8%A6%81%E3%81%AA%E5%A4%89%E6%9B%B4/">参考ページ</a>）回避策として下のような書き方が使えるということがわかりました。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> __construct()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">middleware</span>(<span style="color:#66d9ef">function</span> ($request, $next) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">session</span>(<span style="color:#e6db74">&#39;lang&#39;</span>)) {
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">\App</span><span style="color:#f92672">::</span><span style="color:#a6e22e">setLocale</span>(<span style="color:#a6e22e">session</span>(<span style="color:#e6db74">&#39;lang&#39;</span>));
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> $next($request);
</span></span><span style="display:flex;"><span>    });
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>ですがせっかくなのでミドルウェアを定義してみようと思います。Laravelのバージョンは5.7です。</p>
<h2 id="実装">実装</h2>
<h3 id="ミドルウェア作成">ミドルウェア作成</h3>
<pre tabindex="0"><code>$ php artisan make:middleware Lang
</code></pre><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> <span style="color:#a6e22e">App\Http\Middleware</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Closure</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Lang</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Handle an incoming request.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @param  \Illuminate\Http\Request  $request
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @param  \Closure  $next
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return mixed
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">handle</span>($request, <span style="color:#a6e22e">Closure</span> $next)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">session</span>(<span style="color:#e6db74">&#39;lang&#39;</span>)) {
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">\App</span><span style="color:#f92672">::</span><span style="color:#a6e22e">setLocale</span>(<span style="color:#a6e22e">session</span>(<span style="color:#e6db74">&#39;lang&#39;</span>));
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> $next($request);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="ミドルウェア登録">ミドルウェア登録</h3>
<p><code>app/Http/Kernel.php</code> の <code>$routeMiddleware</code> プロパティに追加します。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * The application&#39;s route middleware.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * These middleware may be assigned to groups or used individually.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * @var array
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> */</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">protected</span> $routeMiddleware <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;auth&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\App\Http\Middleware\Authenticate</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;auth.basic&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\Illuminate\Auth\Middleware\AuthenticateWithBasicAuth</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;bindings&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\Illuminate\Routing\Middleware\SubstituteBindings</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;cache.headers&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\Illuminate\Http\Middleware\SetCacheHeaders</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;can&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\Illuminate\Auth\Middleware\Authorize</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;guest&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\App\Http\Middleware\RedirectIfAuthenticated</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;signed&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\Illuminate\Routing\Middleware\ValidateSignature</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;throttle&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\Illuminate\Routing\Middleware\ThrottleRequests</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;verified&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\Illuminate\Auth\Middleware\EnsureEmailIsVerified</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;lang&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\App\Http\Middleware\Lang</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>, <span style="color:#75715e">// 追加
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>];
</span></span></code></pre></div><p>コントローラのコンストラクタに以下のように書いたり、</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * Create a new controller instance.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * @return void
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> */</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> __construct()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">middleware</span>(<span style="color:#e6db74">&#39;lang&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>ルート定義に書いて使うことができます。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;/&#39;</span>, <span style="color:#66d9ef">function</span> () {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">//
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>})<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">middleware</span>(<span style="color:#e6db74">&#39;lang&#39;</span>);
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>フリーランスになって10年になりました</title>
            <link>https://eza-s.com/blog/archives/259/</link>
            <pubDate>Thu, 06 Sep 2018 09:13:19 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/259/</guid>
            <description>はじめに おかげさまで、フリーランスになって10年になりました。
よく聞く話だとフリーランスになって10年続くのは全体の1割程度ということで、まぁ続かなかった9割のすべてが続けたくても続けられなかったのかというと、事業が順調で法人になったとか、いい会社が見つかって就職したりだとか、そもそも次の仕事見つけるまでのつなぎだったとかあるだろうし、生き残ったからすごい！とは思わないけど、自分でやると決めたことを断念することなく続けることができたのは良かったと思います。
フリーランスというと、始めた当時だと一念発起で独立開業！みたいなイメージがまだあったかもしれないけど、最近では時代の流れかライトな感覚になったように思います。例えると持ち家か賃貸かみたいな、一長一短あるのでお好きな方を選んでください的な。実際ここ数年で自分の周りにもフリーランスになった人が増えました。世はまさにフリーランス戦国時代か、っていうぐらい。まぁ自分の生息範囲が有名企業とは縁のない中小零細Web企業周辺なもんですから、行き着く先は自営業のおっさんっていうキャリアパスになるのもある意味納得な気がします。
そんなこんなでどのようにやってきたかを振り返りつつ、次の10年に向けて考えていきたいと思います。
続けるコツ こういうのを書いておくとブログ記事っぽくなるのかなと思って考えてみたけど、結果として長く続いただけで長く続けようと思ってやってきたわけではなかったw。あえて言うとしたら無理をしないで自分の働きたいと思う働き方をすることじゃないかと思います。
バリバリ働きたい人はバリバリ働けばいいし、あまり働きたくない人はあまり仕事を入れなければいいし、会社員と同じように働きたければ客先常駐すればいいし、出勤したくなければリモートでできる仕事をすればいい、といった具合です。自分がやりたいと思うようにやれているか、というのが第一と思います。
第二に、満足な収入が得られているかどうかということですが、幸いフリーランスで仕事を受けるときって、いくら欲しいか聞かれるので正直に答えましょうw。
この2点が崩されると、やりたいようにやれてない＋満足な収入が得られていない＝最悪となってしまいます。
また、数年で転職というのが珍しくないIT業界ですが、フリーランスだとお付き合いする会社が1社でずっと同じというわけではないので事実上転職、みたいになるのも飽きずに続けられた要因かもしれないです。
次の10年に向けて 年齢的に現在40代で10年後には50代になるのでその頃にどうなってるんだろう、というのがあります。具体的には仕事が減ったり単価が下がるのではないかという懸念ですね。これに対しては今もやってるけど、リモートワークと複業が自分の中ではカギかなと思っています。
リモートワークで直接的なコミュニケーションが無ければ相手が何歳とか関係なくなるのでは、という作戦です。さすがに書いたコードがおじさん臭いと言われてしまえばお手上げですがw。「この人年齢はアレだけどコードはちゃんと書いてるし、Slackとかで普通にやり取りできるから大丈夫」と言ってもらえればアリかと。
また、年齢を重ねるにつれて、プロジェクトにおいてサブ的なポジションのお仕事にシフトしてくるだろうということで、そいう言ったお仕事を複数合わせて一本、を目指すやり方も検討したいです。
とはいえ、自分ひとりだけが年を取るわけではないので蓋を開けてみればそんなに変わってないような気もします。人材を扱う各社もその頃には「50代、60代のエンジニアがアツい」とか言ってそうだしw。
というわけで、今後ともよろしくお願いします。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>おかげさまで、フリーランスになって10年になりました。</p>
<p>よく聞く話だとフリーランスになって10年続くのは全体の1割程度ということで、まぁ続かなかった9割のすべてが続けたくても続けられなかったのかというと、事業が順調で法人になったとか、いい会社が見つかって就職したりだとか、そもそも次の仕事見つけるまでのつなぎだったとかあるだろうし、生き残ったからすごい！とは思わないけど、自分でやると決めたことを断念することなく続けることができたのは良かったと思います。</p>
<p>フリーランスというと、始めた当時だと一念発起で独立開業！みたいなイメージがまだあったかもしれないけど、最近では時代の流れかライトな感覚になったように思います。例えると持ち家か賃貸かみたいな、一長一短あるのでお好きな方を選んでください的な。実際ここ数年で自分の周りにもフリーランスになった人が増えました。世はまさにフリーランス戦国時代か、っていうぐらい。まぁ自分の生息範囲が有名企業とは縁のない中小零細Web企業周辺なもんですから、行き着く先は自営業のおっさんっていうキャリアパスになるのもある意味納得な気がします。</p>
<p>そんなこんなでどのようにやってきたかを振り返りつつ、次の10年に向けて考えていきたいと思います。</p>
<h2 id="続けるコツ">続けるコツ</h2>
<p>こういうのを書いておくとブログ記事っぽくなるのかなと思って考えてみたけど、結果として長く続いただけで長く続けようと思ってやってきたわけではなかったw。あえて言うとしたら無理をしないで自分の働きたいと思う働き方をすることじゃないかと思います。</p>
<p>バリバリ働きたい人はバリバリ働けばいいし、あまり働きたくない人はあまり仕事を入れなければいいし、会社員と同じように働きたければ客先常駐すればいいし、出勤したくなければリモートでできる仕事をすればいい、といった具合です。自分がやりたいと思うようにやれているか、というのが第一と思います。</p>
<p>第二に、満足な収入が得られているかどうかということですが、幸いフリーランスで仕事を受けるときって、いくら欲しいか聞かれるので正直に答えましょうw。</p>
<p>この2点が崩されると、やりたいようにやれてない＋満足な収入が得られていない＝最悪となってしまいます。</p>
<p>また、数年で転職というのが珍しくないIT業界ですが、フリーランスだとお付き合いする会社が1社でずっと同じというわけではないので事実上転職、みたいになるのも飽きずに続けられた要因かもしれないです。</p>
<h2 id="次の10年に向けて">次の10年に向けて</h2>
<p>年齢的に現在40代で10年後には50代になるのでその頃にどうなってるんだろう、というのがあります。具体的には仕事が減ったり単価が下がるのではないかという懸念ですね。これに対しては今もやってるけど、リモートワークと複業が自分の中ではカギかなと思っています。</p>
<p>リモートワークで直接的なコミュニケーションが無ければ相手が何歳とか関係なくなるのでは、という作戦です。さすがに書いたコードがおじさん臭いと言われてしまえばお手上げですがw。「この人年齢はアレだけどコードはちゃんと書いてるし、Slackとかで普通にやり取りできるから大丈夫」と言ってもらえればアリかと。</p>
<p>また、年齢を重ねるにつれて、プロジェクトにおいてサブ的なポジションのお仕事にシフトしてくるだろうということで、そいう言ったお仕事を複数合わせて一本、を目指すやり方も検討したいです。</p>
<p>とはいえ、自分ひとりだけが年を取るわけではないので蓋を開けてみればそんなに変わってないような気もします。人材を扱う各社もその頃には「50代、60代のエンジニアがアツい」とか言ってそうだしw。</p>
<p>というわけで、今後ともよろしくお願いします。</p>
]]></content>
        </item>
        
        <item>
            <title>omniauth-mastodonをForkしてカスタマイズ</title>
            <link>https://eza-s.com/blog/archives/243/</link>
            <pubDate>Wed, 27 Jun 2018 02:04:54 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/243/</guid>
            <description>はじめに マストドンでログインをRailsで実装するを使ってWebサービスを実装中に発見されたomniauth-mastodonの不具合と、その対応内容についてまとめました。
マストドンでログインの流れ マストドンでログインの流れは以下のようになります。
①最初にこのようなダイアログが表示され、username@domain を入力してLoginをクリックします。
②すると入力したdomain のインスタンスのログイン画面に遷移するのでメールアドレスとパスワードを入力してログインすればコールバックを設定した画面に返ってきます。
③返ってきた画面ではインスタンスから取得した各種値の中でもprovider とuid をキーとしてデータの存在をチェックして、存在しなければ新規作成を行います。provider には認証を提供しているサービス名を表す文字列が入ります。マストドンなのでmastodon が、uid にはサービス内で一意の値が入ります。マストドンはインスタンスごとの管理となっているのでusername@domain となります。
不具合内容 uidとして返ってくるのは①の画面で入力したusername@domainなのですが、認証は②の画面で行われ、必ずしも①で入力したusernameでログインしなければいけないわけではありません。
例えば①でuser1@domain と入力して②でuser2 のメールアドレスとパスワードでログインしたらuidにはuser1@domain が返ってきてしまいます。これではアカウントの管理ができません。
対応内容 本家のGitHubを見てみるとこの問題に対するプルリクエストが挙がっていてマージされていました。
ですがその修正内容はuidの中身をusername@domain からid に変更するというものでした。これだとインスタンスが違えば重複が発生するのではないかという疑問と、実装中のWebサービスはusername@domainの形式が来ることを期待しているという都合もあってそのまま使うことが出来ませんでした。
なのでForkしてuidの中身を②でログインしたユーザーのusername@domain を返すよう変更しました。
gem &amp;#39;mastodon-api&amp;#39;, require: &amp;#39;mastodon&amp;#39;, github: &amp;#39;tootsuite/mastodon-api&amp;#39; gem &amp;#39;omniauth-mastodon&amp;#39;, github: &amp;#39;ezaki3/omniauth-mastodon&amp;#39;, branch: &amp;#39;change-uid&amp;#39; gem &amp;#39;omniauth&amp;#39; でインストールすることが出来ます。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p><a href="https://eza-s.com/blog/archives/209">マストドンでログインをRailsで実装する</a>を使ってWebサービスを実装中に発見されたomniauth-mastodonの不具合と、その対応内容についてまとめました。</p>
<h2 id="マストドンでログインの流れ">マストドンでログインの流れ</h2>
<p>マストドンでログインの流れは以下のようになります。</p>
<p><img src="/blog/wp-content/uploads/2018/06/auth-mastodon-300x200.png" alt="Mastodon Login"></p>
<p>①最初にこのようなダイアログが表示され、<code>username@domain</code> を入力してLoginをクリックします。</p>
<p><img src="/blog/wp-content/uploads/2018/06/auth-mastodon2-300x266.png" alt="Mastodon Login2"></p>
<p>②すると入力した<code>domain</code> のインスタンスのログイン画面に遷移するのでメールアドレスとパスワードを入力してログインすればコールバックを設定した画面に返ってきます。</p>
<p>③返ってきた画面ではインスタンスから取得した各種値の中でも<code>provider</code> と<code>uid</code> をキーとしてデータの存在をチェックして、存在しなければ新規作成を行います。<code>provider</code> には認証を提供しているサービス名を表す文字列が入ります。マストドンなので<code>mastodon</code> が、<code>uid</code> にはサービス内で一意の値が入ります。マストドンはインスタンスごとの管理となっているので<code>username@domain</code> となります。</p>
<h2 id="不具合内容">不具合内容</h2>
<p>uidとして返ってくるのは①の画面で入力したusername@domainなのですが、認証は②の画面で行われ、必ずしも①で入力したusernameでログインしなければいけないわけではありません。</p>
<p>例えば①で<code>user1@domain</code> と入力して②で<code>user2</code> のメールアドレスとパスワードでログインしたらuidには<code>user1@domain</code> が返ってきてしまいます。これではアカウントの管理ができません。</p>
<h2 id="対応内容">対応内容</h2>
<p><a href="https://github.com/tootsuite/omniauth-mastodon">本家</a>のGitHubを見てみるとこの問題に対する<a href="https://github.com/tootsuite/omniauth-mastodon/pull/4">プルリクエスト</a>が挙がっていてマージされていました。</p>
<p>ですがその修正内容はuidの中身を<code>username@domain</code> から<code>id</code> に変更するというものでした。これだとインスタンスが違えば重複が発生するのではないかという疑問と、実装中のWebサービスはusername@domainの形式が来ることを期待しているという都合もあってそのまま使うことが出来ませんでした。</p>
<p>なので<a href="https://github.com/ezaki3/omniauth-mastodon/tree/change-uid">Fork</a>してuidの中身を②でログインしたユーザーの<code>username@domain</code> を返すよう変更しました。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;mastodon-api&#39;</span>, require: <span style="color:#e6db74">&#39;mastodon&#39;</span>, <span style="color:#e6db74">github</span>: <span style="color:#e6db74">&#39;tootsuite/mastodon-api&#39;</span>
</span></span><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;omniauth-mastodon&#39;</span>, <span style="color:#e6db74">github</span>: <span style="color:#e6db74">&#39;ezaki3/omniauth-mastodon&#39;</span>, <span style="color:#e6db74">branch</span>: <span style="color:#e6db74">&#39;change-uid&#39;</span>
</span></span><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;omniauth&#39;</span>
</span></span></code></pre></div><p>でインストールすることが出来ます。</p>
]]></content>
        </item>
        
        <item>
            <title>Let’s EncryptでSSLを設定する</title>
            <link>https://eza-s.com/blog/archives/237/</link>
            <pubDate>Wed, 30 May 2018 05:38:45 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/237/</guid>
            <description>はじめに 前回構築した環境にLet&amp;rsquo;s EncryptでSSLを設定したときの作業履歴とメモ。
Firewall設定 httpsのポートを開けます。
# vi /etc/firewalld/zones/public.xml &amp;lt;zone&amp;gt; …省略 &amp;lt;service name=&amp;#34;https&amp;#34;/&amp;gt; &amp;lt;/zone&amp;gt; 設定変更したらサービスを再起動します。
# systemctl restart firewalld certbotのインストール Let&amp;rsquo;s Encryptのクライアントをインストールします。今回はSSHでログインしたユーザーのホームディレクトリで行いました。
$ git clone https://github.com/certbot/certbot 証明書の取得 standaloneプラグイン(自前のHTTPサーバーを起動)で行うため、Nginxを止めておきます。
# systemctl stop nginx インストールしたクライアントのディレクトリに移動して
$ cd certbot $ ./certbot-auto certonly --standalone -t まず、必要なパッケージのインストールについて確認が入るので「y」でインストールする。
次にメールアドレスを聞かれるので入力する
Enter email address (used for urgent renewal and security notices) (Enter &amp;#39;c&amp;#39; to cancel): メールアドレス 次に規約とメール送信について聞かれるので以下のように入力しました。
------------------------------------------------------------------------------- Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v01.</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p><a href="https://eza-s.com/blog/archives/172">前回構築した環境</a>にLet&rsquo;s EncryptでSSLを設定したときの作業履歴とメモ。</p>
<h2 id="firewall設定">Firewall設定</h2>
<p>httpsのポートを開けます。</p>
<pre tabindex="0"><code># vi /etc/firewalld/zones/public.xml
</code></pre><pre tabindex="0"><code>&lt;zone&gt;
  …省略
  &lt;service name=&#34;https&#34;/&gt;
&lt;/zone&gt;
</code></pre><p>設定変更したらサービスを再起動します。</p>
<pre tabindex="0"><code># systemctl restart firewalld
</code></pre><h2 id="certbotのインストール">certbotのインストール</h2>
<p>Let&rsquo;s Encryptのクライアントをインストールします。今回はSSHでログインしたユーザーのホームディレクトリで行いました。</p>
<pre tabindex="0"><code>$ git clone https://github.com/certbot/certbot
</code></pre><h2 id="証明書の取得">証明書の取得</h2>
<p>standaloneプラグイン(自前のHTTPサーバーを起動)で行うため、Nginxを止めておきます。</p>
<pre tabindex="0"><code># systemctl stop nginx
</code></pre><p>インストールしたクライアントのディレクトリに移動して</p>
<pre tabindex="0"><code>$ cd certbot
$ ./certbot-auto certonly --standalone -t
</code></pre><p>まず、必要なパッケージのインストールについて確認が入るので「y」でインストールする。</p>
<p>次にメールアドレスを聞かれるので入力する</p>
<pre tabindex="0"><code>Enter email address (used for urgent renewal and security notices) (Enter &#39;c&#39; to
cancel): メールアドレス
</code></pre><p>次に規約とメール送信について聞かれるので以下のように入力しました。</p>
<pre tabindex="0"><code>-------------------------------------------------------------------------------
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v01.api.letsencrypt.org/directory
-------------------------------------------------------------------------------
(A)gree/(C)ancel: A

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let&#39;s Encrypt project and the non-profit
organization that develops Certbot? We&#39;d like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: N
</code></pre><p>最後にドメインを入力します。</p>
<pre tabindex="0"><code>Please enter in your domain name(s) (comma and/or space separated)  (Enter &#39;c&#39;
to cancel): ドメイン
</code></pre><p>成功すると以下のように表示されます。</p>
<pre tabindex="0"><code>IMPORTANT NOTES:
 - Congratulations!〜以下省略
</code></pre><h2 id="nginxの設定">Nginxの設定</h2>
<p>証明書の設定と、httpへのアクセスをhttpsに転送する設定、あと後述する自動更新のための設定を行います。</p>
<pre tabindex="0"><code># vi /etc/nginx/conf.d/設定ファイル名.conf
</code></pre><pre tabindex="0"><code>server {
    listen 443 ssl; # 80から変更
    proxy_set_header X-Forwarded-Proto https;
   #　以下省略
}
</code></pre><pre tabindex="0"><code># vi /etc/nginx/conf.d/default.conf
</code></pre><pre tabindex="0"><code>server {
    # 自動更新のための設定
    location ^~ /.well-known/acme-challenge/ {
      default_type &#34;text/plain&#34;;
      root        /usr/share/nginx/html;
    }

    # http =&amp;gt; https
    location / {
        return 301 https://$host$request_uri;
    }
}
</code></pre><p>設定したらサービスを起動してhttpsで接続できるか、httpでアクセスしたらhttpsに転送されるか確認します。</p>
<pre tabindex="0"><code># systemctl start nginx
</code></pre><h2 id="証明書の更新">証明書の更新</h2>
<p>証明書を作成するときに指定したモードで更新も行われるけど、standaloneプラグインだとNginxを停止させなければいけないので、webrootプラグインに変更します。</p>
<p>以下のコマンドで実行がてら設定ファイルも更新されます。</p>
<pre tabindex="0"><code>$ ./certbot-auto certonly --webroot -w /usr/share/nginx/html -d ドメイン--agree-tos --force-renewal -n
</code></pre><p>とココまで書いてて気がついたけど<a href="https://letsencrypt.jp/docs/using.html#nginx">Nginxプラグイン</a>というのがあったので最初からそれを使っていたら良さげ。</p>
<h2 id="更新を自動化する">更新を自動化する</h2>
<p>cronを設定します。</p>
<pre tabindex="0"><code>0 4 1 * * /home/ユーザー名/certbot/certbot-auto renew &amp;&amp; /bin/systemctl reload nginx
</code></pre><h2 id="参考">参考</h2>
<p><a href="https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9">https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9</a></p>
]]></content>
        </item>
        
        <item>
            <title>vagrant up がboxのダウンロードでエラーになる</title>
            <link>https://eza-s.com/blog/archives/226/</link>
            <pubDate>Wed, 04 Apr 2018 07:25:32 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/226/</guid>
            <description>マストドンインスタンスをバージョンアップ(v2.1.3 =&amp;gt; v2.3.3)させるためにVagrantなローカル環境で最新コードにてコンフリクト修正したり諸々コマンド入力したりした後、 foreman start してブラウザで確認したらRedis::CommandError in HomeController#index のエラーが。
調べてみると以下の情報が。
https://github.com/tootsuite/mastodon/issues/6399
なるほど、boxが新しくなってるのねということで、vagrant destroyしてvagrant upしたら今度は以下のエラーに。
The box &amp;#39;ubuntu/xenial64&amp;#39; could not be found or could not be accessed in the remote catalog. If this is a private box on HashiCorp&amp;#39;s Atlas, please verify you&amp;#39;re logged in via `vagrant login`. Also, please double-check the name. The expanded URL and error message are shown below: URL: [&amp;#34;https://atlas.hashicorp.com/ubuntu/xenial64&amp;#34;] Error: The requested URL returned error: 404 Not Found 調べてみるとVagrantについてるcurlではダメだという情報があったので</description>
            <content type="html"><![CDATA[<p>マストドンインスタンスをバージョンアップ(v2.1.3 =&gt; v2.3.3)させるためにVagrantなローカル環境で最新コードにてコンフリクト修正したり諸々コマンド入力したりした後、 foreman start してブラウザで確認したら<code>Redis::CommandError in HomeController#index</code> のエラーが。</p>
<p>調べてみると以下の情報が。</p>
<p><a href="https://github.com/tootsuite/mastodon/issues/6399">https://github.com/tootsuite/mastodon/issues/6399</a></p>
<p>なるほど、boxが新しくなってるのねということで、vagrant destroyしてvagrant upしたら今度は以下のエラーに。</p>
<pre tabindex="0"><code>The box &#39;ubuntu/xenial64&#39; could not be found or
could not be accessed in the remote catalog. If this is a private
box on HashiCorp&#39;s Atlas, please verify you&#39;re logged in via
`vagrant login`. Also, please double-check the name. The expanded
URL and error message are shown below:

URL: [&#34;https://atlas.hashicorp.com/ubuntu/xenial64&#34;]
Error: The requested URL returned error: 404 Not Found
</code></pre><p>調べてみるとVagrantについてるcurlではダメだという情報があったので</p>
<pre tabindex="0"><code>sudo rm /opt/vagrant/embedded/bin/curl
</code></pre><p>してみたけど変わらず。Vagrantをアップデート(1.9.2 =&gt; 2.0.3)したらOKでした。</p>
<p>余談ですがVagrantアップデート後</p>
<pre tabindex="0"><code>vagrant plugin repair
</code></pre><p>しました。</p>
]]></content>
        </item>
        
        <item>
            <title>Laravelでバリデーションエラーを個別に表示する</title>
            <link>https://eza-s.com/blog/archives/222/</link>
            <pubDate>Thu, 15 Feb 2018 09:25:34 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/222/</guid>
            <description>https://eza-s.com/blog/archives/56に書いた時は省略してしまってましたが、その後必要に迫られて実装したので作業ログとして残しておきます。
フォームの入力エラー表示で入力項目の下に個別にエラーを表示させるやり方です。
&amp;lt;div class=&amp;#34;form-group&amp;#34;&amp;gt; &amp;lt;label for=&amp;#34;name&amp;#34;&amp;gt;名前&amp;lt;/label&amp;gt; &amp;lt;input name=&amp;#34;name&amp;#34; type=&amp;#34;text&amp;#34; class=&amp;#34;form-control @if($errors-&amp;gt;has(&amp;#39;name&amp;#39;)) is-invalid @endif&amp;#34; id=&amp;#34;name&amp;#34; value=&amp;#34;{{ old(&amp;#39;name&amp;#39;) }}&amp;#34;&amp;gt; &amp;lt;div class=&amp;#34;invalid-feedback&amp;#34;&amp;gt; @foreach ($errors-&amp;gt;get(&amp;#39;name&amp;#39;) as $error) {{ $error }}&amp;lt;br&amp;gt; @endforeach &amp;lt;/div&amp;gt; &amp;lt;/div&amp;gt; Laravel5.4、Bootstrap v4.0を使っています。@if($errors-&amp;gt;has(&amp;amp;#8216;name&amp;amp;#8217;)) でエラーかどうか判定してclassを付加し、@foreach ($errors-&amp;gt;get(&#39;name&#39;) as $error) でエラーメッセージを取得しています。</description>
            <content type="html"><![CDATA[<p><a href="https://eza-s.com/blog/archives/56">https://eza-s.com/blog/archives/56</a>に書いた時は省略してしまってましたが、その後必要に迫られて実装したので作業ログとして残しておきます。</p>
<p>フォームの入力エラー表示で入力項目の下に個別にエラーを表示させるやり方です。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">label</span> <span style="color:#66d9ef">for</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">名前</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">label</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-control @if(</span><span style="color:#e6db74">$errors-&gt;has</span><span style="color:#e6db74">(&#39;name&#39;)) is-invalid @endif&#34;</span> <span style="color:#a6e22e">id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ old(&#39;name&#39;) }}&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;invalid-feedback&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">@</span><span style="color:#66d9ef">foreach</span> ($errors<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;name&#39;</span>) <span style="color:#66d9ef">as</span> $error)
</span></span><span style="display:flex;"><span>            {{ $error }}<span style="color:#f92672">&lt;</span><span style="color:#a6e22e">br</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">@</span><span style="color:#66d9ef">endforeach</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span></code></pre></div><p>Laravel5.4、Bootstrap v4.0を使っています。<code>@if($errors-&gt;has(&amp;#8216;name&amp;#8217;))</code> でエラーかどうか判定してclassを付加し、<code>@foreach ($errors-&gt;get('name') as $error)</code> でエラーメッセージを取得しています。</p>
]]></content>
        </item>
        
        <item>
            <title>Mastodon API Ruby Gem インストール時の注意点</title>
            <link>https://eza-s.com/blog/archives/219/</link>
            <pubDate>Wed, 24 Jan 2018 08:57:38 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/219/</guid>
            <description>前回インストールしたmastodon-apiを使って投稿をしようとした時の事です。
シンプルに
client = Mastodon::REST::Client.new(base_url: &amp;#39;https://instance_domain&amp;#39;, bearer_token: &amp;#39;your_access_token&amp;#39;) client.create_status(&amp;#39;Hello world&amp;#39;) だと投稿出来たのですが、公開範囲等のオプションを追加して
client.create_status(&amp;#39;Hello world&amp;#39;, params) (paramsにオプションが定義されている)だとエラーとなり投稿できませんでした。メディアのアップロードも出来ませんでした。パラメータの指定の仕方はソースコードを確認してるのに、どうしてだろうと思ってたら、どうやら
gem &amp;#39;mastodon-api&amp;#39;, require: &amp;#39;mastodon&amp;#39; でインストールされるのがgithub上のより古いみたいで
gem &amp;#39;mastodon-api&amp;#39;, require: &amp;#39;mastodon&amp;#39;, github: &amp;#39;tootsuite/mastodon-api&amp;#39; とすれば動くようになりました。</description>
            <content type="html"><![CDATA[<p><a href="https://eza-s.com/blog/archives/209">前回</a>インストールした<a href="https://github.com/tootsuite/mastodon-api">mastodon-api</a>を使って投稿をしようとした時の事です。</p>
<p>シンプルに</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>client <span style="color:#f92672">=</span> <span style="color:#66d9ef">Mastodon</span><span style="color:#f92672">::</span><span style="color:#66d9ef">REST</span><span style="color:#f92672">::</span><span style="color:#66d9ef">Client</span><span style="color:#f92672">.</span>new(<span style="color:#e6db74">base_url</span>: <span style="color:#e6db74">&#39;https://instance_domain&#39;</span>, <span style="color:#e6db74">bearer_token</span>: <span style="color:#e6db74">&#39;your_access_token&#39;</span>)
</span></span><span style="display:flex;"><span>client<span style="color:#f92672">.</span>create_status(<span style="color:#e6db74">&#39;Hello world&#39;</span>)
</span></span></code></pre></div><p>だと投稿出来たのですが、公開範囲等のオプションを追加して</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>client<span style="color:#f92672">.</span>create_status(<span style="color:#e6db74">&#39;Hello world&#39;</span>, params)
</span></span></code></pre></div><p>(paramsにオプションが定義されている)だとエラーとなり投稿できませんでした。メディアのアップロードも出来ませんでした。パラメータの指定の仕方はソースコードを確認してるのに、どうしてだろうと思ってたら、どうやら</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;mastodon-api&#39;</span>, require: <span style="color:#e6db74">&#39;mastodon&#39;</span>
</span></span></code></pre></div><p>でインストールされるのがgithub上のより古いみたいで</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;mastodon-api&#39;</span>, require: <span style="color:#e6db74">&#39;mastodon&#39;</span>, <span style="color:#e6db74">github</span>: <span style="color:#e6db74">&#39;tootsuite/mastodon-api&#39;</span>
</span></span></code></pre></div><p>とすれば動くようになりました。</p>
]]></content>
        </item>
        
        <item>
            <title>マストドンでログインをRailsで実装する</title>
            <link>https://eza-s.com/blog/archives/209/</link>
            <pubDate>Wed, 20 Dec 2017 05:46:07 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/209/</guid>
            <description>はじめに omniauth-mastodonというgemを使ってマストドンでログインをRailsで実装する手順についてまとめました。また、ベースとなっているomniauthで必要な項目についても触れています。
omniauth-mastodon インストール # Gemfile gem &amp;#39;mastodon-api&amp;#39;, require: &amp;#39;mastodon&amp;#39; gem &amp;#39;omniauth-mastodon&amp;#39; gem &amp;#39;omniauth&amp;#39; モデルの作成 後述する設定で使用するモデルを作成します。
$ rails generate model MastodonClient domain:string client_id:string client_secret:string 設定 マストドンはtwitter等と違ってドメインの異なる複数のインスタンスが存在します。twitterの場合は別途設定画面からアプリケーションを登録してその情報を使用するのですが、マストドンでは動的に取得してDBに保持します。
# config/initializers/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :mastodon, scope: &amp;#39;read write follow&amp;#39;, credentials: lambda { |domain, callback_url| Rails.logger.info &amp;#34;Requested credentials for #{domain} with callback URL #{callback_url}&amp;#34; existing = MastodonClient.find_by(domain: domain) return [existing.client_id, existing.client_secret] unless existing.nil? client = Mastodon::REST::Client.new(base_url: &amp;#34;https://#{domain}&amp;#34;) app = client.create_app(&amp;#39;OmniAuth Test Harness&amp;#39;, callback_url, &amp;#39;read write follow&amp;#39;) MastodonClient.</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p><a href="https://github.com/tootsuite/omniauth-mastodon">omniauth-mastodon</a>というgemを使ってマストドンでログインをRailsで実装する手順についてまとめました。また、ベースとなっている<a href="https://github.com/omniauth/omniauth">omniauth</a>で必要な項目についても触れています。</p>
<h2 id="omniauth-mastodon">omniauth-mastodon</h2>
<h3 id="インストール">インストール</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># Gemfile</span>
</span></span><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;mastodon-api&#39;</span>, require: <span style="color:#e6db74">&#39;mastodon&#39;</span>
</span></span><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;omniauth-mastodon&#39;</span>
</span></span><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;omniauth&#39;</span>
</span></span></code></pre></div><h3 id="モデルの作成">モデルの作成</h3>
<p>後述する設定で使用するモデルを作成します。</p>
<pre tabindex="0"><code>$ rails generate model MastodonClient domain:string client_id:string client_secret:string
</code></pre><h3 id="設定">設定</h3>
<p>マストドンはtwitter等と違ってドメインの異なる複数のインスタンスが存在します。twitterの場合は別途設定画面からアプリケーションを登録してその情報を使用するのですが、マストドンでは動的に取得してDBに保持します。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># config/initializers/omniauth.rb</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">Rails</span><span style="color:#f92672">.</span>application<span style="color:#f92672">.</span>config<span style="color:#f92672">.</span>middleware<span style="color:#f92672">.</span>use <span style="color:#66d9ef">OmniAuth</span><span style="color:#f92672">::</span><span style="color:#66d9ef">Builder</span> <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>  provider <span style="color:#e6db74">:mastodon</span>, <span style="color:#e6db74">scope</span>: <span style="color:#e6db74">&#39;read write follow&#39;</span>, <span style="color:#e6db74">credentials</span>: lambda { <span style="color:#f92672">|</span>domain, callback_url<span style="color:#f92672">|</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">Rails</span><span style="color:#f92672">.</span>logger<span style="color:#f92672">.</span>info <span style="color:#e6db74">&#34;Requested credentials for </span><span style="color:#e6db74">#{</span>domain<span style="color:#e6db74">}</span><span style="color:#e6db74"> with callback URL </span><span style="color:#e6db74">#{</span>callback_url<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    existing <span style="color:#f92672">=</span> <span style="color:#66d9ef">MastodonClient</span><span style="color:#f92672">.</span>find_by(<span style="color:#e6db74">domain</span>: domain)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#f92672">[</span>existing<span style="color:#f92672">.</span>client_id, existing<span style="color:#f92672">.</span>client_secret<span style="color:#f92672">]</span> <span style="color:#66d9ef">unless</span> existing<span style="color:#f92672">.</span>nil?
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    client <span style="color:#f92672">=</span> <span style="color:#66d9ef">Mastodon</span><span style="color:#f92672">::</span><span style="color:#66d9ef">REST</span><span style="color:#f92672">::</span><span style="color:#66d9ef">Client</span><span style="color:#f92672">.</span>new(<span style="color:#e6db74">base_url</span>: <span style="color:#e6db74">&#34;https://</span><span style="color:#e6db74">#{</span>domain<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>    app <span style="color:#f92672">=</span> client<span style="color:#f92672">.</span>create_app(<span style="color:#e6db74">&#39;OmniAuth Test Harness&#39;</span>, callback_url, <span style="color:#e6db74">&#39;read write follow&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">MastodonClient</span><span style="color:#f92672">.</span>create!(<span style="color:#e6db74">domain</span>: domain, <span style="color:#e6db74">client_id</span>: app<span style="color:#f92672">.</span>client_id, <span style="color:#e6db74">client_secret</span>: app<span style="color:#f92672">.</span>client_secret)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">[</span>app<span style="color:#f92672">.</span>client_id, app<span style="color:#f92672">.</span>client_secret<span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div><p>本家のREADMEでは</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>app <span style="color:#f92672">=</span> client<span style="color:#f92672">.</span>create_app(<span style="color:#e6db74">&#39;OmniAuth Test Harness&#39;</span>, callback_url, <span style="color:#e6db74">&#39;read write follow&#39;</span>)
</span></span></code></pre></div><p>に<code>'read write follow'</code> の指定はありませんが、省略したままだと</p>
<p><code>invalid_scope: 要求されたアクセス権は無効であるか、不明、または不正なフォーマットです。</code></p>
<p>のエラーとなります。また、第4引数として<code>@param website [String]</code> を渡すこともできます。認証済みアプリ一覧にWebsiteへのリンクを貼ることが出来ますので必要に応じてWebsiteのアドレスを入れます。</p>
<p><code>/auth/mastodon</code> にアクセスするとマストドンでログインが始まります。</p>
<h2 id="omniauth">omniauth</h2>
<h3 id="設定-1">設定</h3>
<p>ここでは<code>User</code> モデルに保持する想定です。まずルーティングの設定をします。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># config/roues.rb</span>
</span></span><span style="display:flex;"><span>get <span style="color:#e6db74">&#39;/auth/:provider/callback&#39;</span>, <span style="color:#e6db74">to</span>: <span style="color:#e6db74">&#39;sessions#create&#39;</span>
</span></span></code></pre></div><p>マストドンでログインが完了した時に返ってくる画面になります。</p>
<h3 id="実装">実装</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># app/controllers/sessions_controller.rb</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">SessionsController</span> <span style="color:#f92672">&lt;</span> <span style="color:#66d9ef">ApplicationController</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">create</span>
</span></span><span style="display:flex;"><span>    @user <span style="color:#f92672">=</span> <span style="color:#66d9ef">User</span><span style="color:#f92672">.</span>find_or_create_from_auth(request<span style="color:#f92672">.</span>env<span style="color:#f92672">[</span><span style="color:#e6db74">&#39;omniauth.auth&#39;</span><span style="color:#f92672">]</span>)
</span></span><span style="display:flex;"><span>    self<span style="color:#f92672">.</span>current_user <span style="color:#f92672">=</span> @user
</span></span><span style="display:flex;"><span>    redirect_to <span style="color:#e6db74">&#39;/&#39;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># app/models/user.rb</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">User</span> <span style="color:#f92672">&lt;</span> <span style="color:#66d9ef">ApplicationRecord</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">self</span><span style="color:#f92672">.</span><span style="color:#a6e22e">find_or_create_from_auth</span>(auth)
</span></span><span style="display:flex;"><span>    provider <span style="color:#f92672">=</span> auth<span style="color:#f92672">[</span><span style="color:#e6db74">:provider</span><span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span>    uid <span style="color:#f92672">=</span> auth<span style="color:#f92672">[</span><span style="color:#e6db74">:uid</span><span style="color:#f92672">]</span>
</span></span><span style="display:flex;"><span>    token <span style="color:#f92672">=</span> auth<span style="color:#f92672">[</span><span style="color:#e6db74">:credentials</span><span style="color:#f92672">].</span>token
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    self<span style="color:#f92672">.</span>find_or_create_by(<span style="color:#e6db74">provider</span>: provider, <span style="color:#e6db74">uid</span>: uid) <span style="color:#66d9ef">do</span> <span style="color:#f92672">|</span>user<span style="color:#f92672">|</span>
</span></span><span style="display:flex;"><span>      user<span style="color:#f92672">.</span>token <span style="color:#f92672">=</span> token
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div><p>認証情報を登録するための最低限の実装例です。</p>
<h2 id="追記">追記</h2>
<p>マストドンでログイン実装後に発覚した問題について以下の記事にまとめています。</p>
<p><a href="https://eza-s.com/blog/archives/219">Mastodon API Ruby Gem インストール時の注意点</a></p>
<p><a href="https://eza-s.com/blog/archives/243">omniauth-mastodonをForkしてカスタマイズ</a></p>
]]></content>
        </item>
        
        <item>
            <title>Railsのモデルでテーブルに存在しない項目を扱う</title>
            <link>https://eza-s.com/blog/archives/203/</link>
            <pubDate>Wed, 15 Nov 2017 03:14:51 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/203/</guid>
            <description>Railsに限らずですがORMなモデルを使うと特に意識しなくても対応するテーブルのカラムを使用することが出来ます。
p = Product.new p.name = &amp;#34;Some Book&amp;#34; puts p.name # &amp;#34;Some Book&amp;#34; では、テーブルに存在しない項目はどのようにすればよいか？モデルにVirtual Attributesを定義すれば出来ました。
attr_accessor :some_attribute これでDBには保持しないけどパラメータとして受け取って何らかの処理を行う事が出来ます。</description>
            <content type="html"><![CDATA[<p>Railsに限らずですがORMなモデルを使うと特に意識しなくても対応するテーブルのカラムを使用することが出来ます。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>p <span style="color:#f92672">=</span> <span style="color:#66d9ef">Product</span><span style="color:#f92672">.</span>new
</span></span><span style="display:flex;"><span>p<span style="color:#f92672">.</span>name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Some Book&#34;</span>
</span></span><span style="display:flex;"><span>puts p<span style="color:#f92672">.</span>name <span style="color:#75715e"># &#34;Some Book&#34;</span>
</span></span></code></pre></div><p>では、テーブルに存在しない項目はどのようにすればよいか？モデルにVirtual Attributesを定義すれば出来ました。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#66d9ef">attr_accessor</span> <span style="color:#e6db74">:some_attribute</span>
</span></span></code></pre></div><p>これでDBには保持しないけどパラメータとして受け取って何らかの処理を行う事が出来ます。</p>
]]></content>
        </item>
        
        <item>
            <title>ブログを始めて1年になりました</title>
            <link>https://eza-s.com/blog/archives/201/</link>
            <pubDate>Fri, 10 Nov 2017 06:41:04 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/201/</guid>
            <description>ブログを始めて1年になりましたので振り返り的な雑記を。
そもそも今更ながらブログを始めたのは社内技術勉強会で「技術ブログを書くことについて」発表しましたを見たのがきっかけでした。幾つかポイントが書かれていますが「自分のために書く」というのが自分の中で大きかったです。年齢的に40歳を超えてからさすがに以前ほど色々と覚えていられなくなったので書いておいた方が良いと思うようになりました。
とは言え実際に始めてみると何かと気になるもので、特にこれと言った投稿も出来なくて、ググれば他にいくらでも出てきそうな事だったりマニュアルに書いてるだろそれ、みたいな事しか書けないなと勝手にヘコんでますが、何か独自の情報を発信するとなるとハードルが上がってしまうので、あくまでも個人的に備忘録や作業履歴として書いてる事が他の誰かにとっても役に立ったら良いかなぐらいで考えるようにしています。
あとは普段リモートワークをしている事が多いので、近くにいない分、対応した内容をできるだけ丁寧に伝えたいと思ったり、ドキュメントを残しておくとまた別の機会に似たような仕事があった時に参照出来たり、そういったドキュメントを書く練習にもなっています。
そんなブログですが一部の記事が検索で上位に来るらしく多少はアクセスがあったり、顔を合わせる機会の多い同業の方は関心事も似ているのか「調べたいことがあってググったらezaki3のブログが出てきた」とか言ってもらえたりして、そういうのは励みになります。
アクセス数で言えば、先述した自分でこれは独自の情報と思う記事より、他にいくらでもありそう／マニュアルに書いてそう系の記事の方がアクセス数があったりなんかしてます。独自＝他の人が書かない事＝そもそも需要がない、という事なのだと思います。
もう少し特定の言語やフレームワークに話題を絞った方が近頃のネットの使い方としては良いのかもしれませんが、自分自身が古いタイプの何でも屋なのでもうしばらく雑多な感じで様子を見ようと思います。
ブログを書くようになってから、作業をしていてハマった時なんかは逆に「ブログネタゲットだぜ」と思えるようになったのは良かったですw</description>
            <content type="html"><![CDATA[<p>ブログを始めて1年になりましたので振り返り的な雑記を。</p>
<p>そもそも今更ながらブログを始めたのは<a href="http://developer.hatenastaff.com/entry/2016/09/02/150708">社内技術勉強会で「技術ブログを書くことについて」発表しました</a>を見たのがきっかけでした。幾つかポイントが書かれていますが「自分のために書く」というのが自分の中で大きかったです。年齢的に40歳を超えてからさすがに以前ほど色々と覚えていられなくなったので書いておいた方が良いと思うようになりました。</p>
<p>とは言え実際に始めてみると何かと気になるもので、特にこれと言った投稿も出来なくて、ググれば他にいくらでも出てきそうな事だったりマニュアルに書いてるだろそれ、みたいな事しか書けないなと勝手にヘコんでますが、何か独自の情報を発信するとなるとハードルが上がってしまうので、あくまでも個人的に備忘録や作業履歴として書いてる事が他の誰かにとっても役に立ったら良いかなぐらいで考えるようにしています。</p>
<p>あとは普段リモートワークをしている事が多いので、近くにいない分、対応した内容をできるだけ丁寧に伝えたいと思ったり、ドキュメントを残しておくとまた別の機会に似たような仕事があった時に参照出来たり、そういったドキュメントを書く練習にもなっています。</p>
<p>そんなブログですが一部の記事が検索で上位に来るらしく多少はアクセスがあったり、顔を合わせる機会の多い同業の方は関心事も似ているのか「調べたいことがあってググったらezaki3のブログが出てきた」とか言ってもらえたりして、そういうのは励みになります。</p>
<p>アクセス数で言えば、先述した自分でこれは独自の情報と思う記事より、他にいくらでもありそう／マニュアルに書いてそう系の記事の方がアクセス数があったりなんかしてます。独自＝他の人が書かない事＝そもそも需要がない、という事なのだと思います。</p>
<p>もう少し特定の言語やフレームワークに話題を絞った方が近頃のネットの使い方としては良いのかもしれませんが、自分自身が古いタイプの何でも屋なのでもうしばらく雑多な感じで様子を見ようと思います。</p>
<p>ブログを書くようになってから、作業をしていてハマった時なんかは逆に「ブログネタゲットだぜ」と思えるようになったのは良かったですw</p>
]]></content>
        </item>
        
        <item>
            <title>マストドンをv1.4.6→v1.6.0にアップデートした時の作業メモ</title>
            <link>https://eza-s.com/blog/archives/196/</link>
            <pubDate>Wed, 11 Oct 2017 08:40:40 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/196/</guid>
            <description>はじめに さくらのクラウドのスタートアップスクリプトで立てたインスタンス（CentOS、non-Docker）です。ソースコードはローカル環境でマージ、確認、プッシュ済みなのでそこの作業は省略します。
パッケージの追加 libicu-dev、libidn11-devが必要になりますがCentOSではパッケージ名が異なります。
$ yum install libicu-devel libidn-devel ソースコードの最新化 マストドンのプロジェクトルートディレクトリで行います。
$ git pull origin develop アップデート gem、yarnで追加されたモジュールをインストールします。
$ bundle install $ yarn install Web Push notificationsを有効にするためのkeyを作成します。
$ RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key 画面上に表示された情報を.env.production に追記します。
DBのmigrate、js等ファイルのビルドを行います。
$ RAILS_ENV=production bundle exec rails db:migrate $ RAILS_ENV=production bundle exec rails assets:precompile 古いサムネイルを削除します。
$ RAILS_ENV=production bundle exec rails mastodon:maintenance:remove_deprecated_preview_cards ここまでです。最後にサービスを再起動します。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>さくらのクラウドのスタートアップスクリプトで立てたインスタンス（CentOS、non-Docker）です。ソースコードはローカル環境でマージ、確認、プッシュ済みなのでそこの作業は省略します。</p>
<h2 id="パッケージの追加">パッケージの追加</h2>
<p>libicu-dev、libidn11-devが必要になりますがCentOSではパッケージ名が異なります。</p>
<pre tabindex="0"><code>$ yum install libicu-devel libidn-devel
</code></pre><h2 id="ソースコードの最新化">ソースコードの最新化</h2>
<p>マストドンのプロジェクトルートディレクトリで行います。</p>
<pre tabindex="0"><code>$ git pull origin develop
</code></pre><h2 id="アップデート">アップデート</h2>
<p>gem、yarnで追加されたモジュールをインストールします。</p>
<pre tabindex="0"><code>$ bundle install
$ yarn install
</code></pre><p>Web Push notificationsを有効にするためのkeyを作成します。</p>
<pre tabindex="0"><code>$ RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key
</code></pre><p>画面上に表示された情報を<code>.env.production</code> に追記します。</p>
<p>DBのmigrate、js等ファイルのビルドを行います。</p>
<pre tabindex="0"><code>$ RAILS_ENV=production bundle exec rails db:migrate
$ RAILS_ENV=production bundle exec rails assets:precompile
</code></pre><p>古いサムネイルを削除します。</p>
<pre tabindex="0"><code>$ RAILS_ENV=production bundle exec rails mastodon:maintenance:remove_deprecated_preview_cards
</code></pre><p>ここまでです。最後にサービスを再起動します。</p>
]]></content>
        </item>
        
        <item>
            <title>マストドンインスタンスをカスタマイズ(アイマストドンのpngをjpgに変換・保存)</title>
            <link>https://eza-s.com/blog/archives/192/</link>
            <pubDate>Wed, 20 Sep 2017 02:47:35 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/192/</guid>
            <description>はじめに 詳しくはこちらのスライドにて =&amp;gt; pngをjpgに変換・保存する in アイマストドン
私がお手伝いしているインスタンスもスマホゲーム利用者向けのインスタンスなので同等の効果が期待できそう、ということで移植させていただきました。
実装 実装内容についてはGitHubで公開しています。
https://github.com/mimumemo/mastodon/pull/3/files</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>詳しくはこちらのスライドにて =&gt; <a href="http://niconare.nicovideo.jp/watch/kn2531">pngをjpgに変換・保存する in アイマストドン</a></p>
<p>私がお手伝いしているインスタンスもスマホゲーム利用者向けのインスタンスなので同等の効果が期待できそう、ということで移植させていただきました。</p>
<h2 id="実装">実装</h2>
<p>実装内容についてはGitHubで公開しています。</p>
<p><a href="https://github.com/mimumemo/mastodon/pull/3/files">https://github.com/mimumemo/mastodon/pull/3/files</a><!-- raw HTML omitted --></p>
]]></content>
        </item>
        
        <item>
            <title>マストドンインスタンスをカスタマイズ(Pawooのおすすめタグ機能を実装する)</title>
            <link>https://eza-s.com/blog/archives/188/</link>
            <pubDate>Thu, 14 Sep 2017 02:38:50 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/188/</guid>
            <description>はじめに 前回に続いて今回はPawooに実装されているおすすめタグ機能（赤枠の部分）を移植しました。
ざっくりと以下の機能があります。
おすすめタグは管理者権限を持つユーザーがユーザー設定→管理→運営タグで登録／編集／削除ができる おすすめタグ一覧取得APIからデータを取得して表示する おすすめタグ右側の鉛筆ボタンを押すとトゥート入力欄にタグが入力される 実装 実装内容についてはGitHubで公開しています。
https://github.com/mimumemo/mastodon/pull/2/files</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p><a href="https://eza-s.com/blog/archives/162">前回</a>に続いて今回はPawooに実装されているおすすめタグ機能（赤枠の部分）を移植しました。</p>
<p><img src="/blog/wp-content/uploads/2017/09/pawoo.net-web-statuses-newiPhone-6-Plus-169x300.png" alt="おすすめタグ"></p>
<p>ざっくりと以下の機能があります。</p>
<ul>
<li>おすすめタグは管理者権限を持つユーザーがユーザー設定→管理→運営タグで登録／編集／削除ができる</li>
<li>おすすめタグ一覧取得APIからデータを取得して表示する</li>
<li>おすすめタグ右側の鉛筆ボタンを押すとトゥート入力欄にタグが入力される</li>
</ul>
<h2 id="実装">実装</h2>
<p>実装内容についてはGitHubで公開しています。</p>
<p><a href="https://github.com/mimumemo/mastodon/pull/2/files">https://github.com/mimumemo/mastodon/pull/2/files</a></p>
]]></content>
        </item>
        
        <item>
            <title>Yarn &#43; webpack &#43; BabelでReactの開発環境を作る</title>
            <link>https://eza-s.com/blog/archives/182/</link>
            <pubDate>Wed, 06 Sep 2017 06:47:46 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/182/</guid>
            <description>はじめに 最近マストドンのカスタマイズとかでReactを触るのでこの機会に勉強したく、まずは開発環境を作るところから。
MacでHomebrew、Node.jsはインストール済み。
手順 Yarnのインストール $ brew install yarn プロジェクトフォルダ作成 $ mkdir project-name $ cd project-name 初期化 $ yarn init 入力項目はいったんデフォルトのままで。pakages.jsonが作成されます。
パッケージインストール $ yarn add react react-dom $ yarn add webpack webpack-dev-server babel-loader babel-core babel-preset-react babel-preset-es2015 --dev ファイル追加・編集 src/app.jsx import React from &amp;#39;react&amp;#39;; import ReactDOM from &amp;#39;react-dom&amp;#39;; ReactDOM.render( &amp;lt;h1&amp;gt;Hello, world!&amp;lt;/h1&amp;gt;, document.getElementById(&amp;#39;root&amp;#39;) ); dist/index.html &amp;lt;!doctype html&amp;gt; &amp;lt;html&amp;gt; &amp;lt;head&amp;gt; &amp;lt;meta charset=&amp;#34;utf-8&amp;#34;&amp;gt; &amp;lt;title&amp;gt;Hello React&amp;lt;/title&amp;gt; &amp;lt;/head&amp;gt; &amp;lt;body&amp;gt; &amp;lt;div id=&amp;#34;root&amp;#34;&amp;gt;&amp;lt;/div&amp;gt; &amp;lt;script src=&amp;#34;./bundle.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt; &amp;lt;/body&amp;gt; &amp;lt;/html&amp;gt; webpack.config.js var path = require(&amp;#39;path&amp;#39;); module.</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>最近マストドンのカスタマイズとかでReactを触るのでこの機会に勉強したく、まずは開発環境を作るところから。</p>
<p>MacでHomebrew、Node.jsはインストール済み。</p>
<h2 id="手順">手順</h2>
<h3 id="yarnのインストール">Yarnのインストール</h3>
<pre tabindex="0"><code>$ brew install yarn
</code></pre><h3 id="プロジェクトフォルダ作成">プロジェクトフォルダ作成</h3>
<pre tabindex="0"><code>$ mkdir project-name
$ cd project-name
</code></pre><h3 id="初期化">初期化</h3>
<pre tabindex="0"><code>$ yarn init
</code></pre><p>入力項目はいったんデフォルトのままで。pakages.jsonが作成されます。</p>
<h3 id="パッケージインストール">パッケージインストール</h3>
<pre tabindex="0"><code>$ yarn add react react-dom 
$ yarn add webpack webpack-dev-server babel-loader babel-core babel-preset-react babel-preset-es2015 --dev
</code></pre><h3 id="ファイル追加編集">ファイル追加・編集</h3>
<h4 id="srcappjsx">src/app.jsx</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">import</span> <span style="color:#a6e22e">React</span> <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;react&#39;</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">import</span> <span style="color:#a6e22e">ReactDOM</span> <span style="color:#a6e22e">from</span> <span style="color:#e6db74">&#39;react-dom&#39;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">ReactDOM</span>.<span style="color:#a6e22e">render</span>(
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">h1</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">Hello</span>, <span style="color:#a6e22e">world</span><span style="color:#f92672">!&lt;</span><span style="color:#960050;background-color:#1e0010">/h1&gt;,</span>
</span></span><span style="display:flex;"><span>  document.<span style="color:#a6e22e">getElementById</span>(<span style="color:#e6db74">&#39;root&#39;</span>)
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></div><h4 id="distindexhtml">dist/index.html</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#75715e">&lt;!doctype html&gt;</span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">html</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">head</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">meta</span> <span style="color:#a6e22e">charset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;utf-8&#34;</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">title</span>&gt;Hello React&lt;/<span style="color:#f92672">title</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">head</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">body</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;root&#34;</span>&gt;&lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">script</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;./bundle.js&#34;</span>&gt;&lt;/<span style="color:#f92672">script</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">body</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">html</span>&gt;
</span></span></code></pre></div><h4 id="webpackconfigjs">webpack.config.js</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">var</span> <span style="color:#a6e22e">path</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">require</span>(<span style="color:#e6db74">&#39;path&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">module</span>.<span style="color:#a6e22e">exports</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">entry</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;./src/app.jsx&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">output</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">path</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">resolve</span>(<span style="color:#e6db74">&#39;dist&#39;</span>),
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">filename</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;bundle.js&#39;</span>
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">devtool</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;inline-source-map&#39;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">module</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">rules</span><span style="color:#f92672">:</span> [
</span></span><span style="display:flex;"><span>      {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">test</span><span style="color:#f92672">:</span> <span style="color:#e6db74">/\.(js|jsx)$/</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">loader</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;babel-loader&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">options</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>          <span style="color:#a6e22e">presets</span><span style="color:#f92672">:</span> [<span style="color:#e6db74">&#39;es2015&#39;</span>, <span style="color:#e6db74">&#39;react&#39;</span>]
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    ]
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">devServer</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">contentBase</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">path</span>.<span style="color:#a6e22e">resolve</span>(<span style="color:#e6db74">&#39;dist&#39;</span>),
</span></span><span style="display:flex;"><span>  },
</span></span><span style="display:flex;"><span>};
</span></span></code></pre></div><h4 id="packagesjson">packages.json</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#e6db74">&#34;scripts&#34;</span><span style="color:#960050;background-color:#1e0010">:</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;build&#34;</span>: <span style="color:#e6db74">&#34;webpack --progress&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;start&#34;</span>: <span style="color:#e6db74">&#34;webpack-dev-server --inline&#34;</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>を追加。</p>
<h3 id="動作確認">動作確認</h3>
<pre tabindex="0"><code>$ yarn start
</code></pre><p>localhost:8080 で確認できます。jsを編集すると自動でビルドとブラウザのリロードが行われます。</p>
<h3 id="ビルド">ビルド</h3>
<pre tabindex="0"><code>$ yarn build
</code></pre>]]></content>
        </item>
        
        <item>
            <title>Rails本番環境構築メモ</title>
            <link>https://eza-s.com/blog/archives/172/</link>
            <pubDate>Wed, 02 Aug 2017 05:44:23 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/172/</guid>
            <description>はじめに CentOS7 + Rails5 + Nginx + puma + PostgreSQLで本番環境を構築したときの作業履歴とメモ。サーバーはさくらのクラウドです。
初期設定 Rails本番環境とは直接関係ない項目もありますが下準備&amp;amp;最低限必要な設定として行いました。
一般ユーザーの作成&amp;amp;sudo&amp;amp;ssh接続設定（公開鍵認証） 【さくらのVPS】サーバの初期設定ガイド
を参考に設定しました。
yum-cronによるパッケージの自動更新 インストール # yum -y install yum-cron 設定 # vi /etc/yum/yum-cron.conf 自動更新を有効に設定
apply_updates = yes サービス起動&amp;amp;自動起動設定 # systemctl start yum-cron # systemctl enable yum-cron Firewall設定 httpのポートを開けます。また、作業途中の確認用にポート3000も開けます。
# vi /etc/firewalld/zones/public.xml &amp;lt;zone&amp;gt; …省略 &amp;lt;service name=&amp;#34;http&amp;#34;/&amp;gt; &amp;lt;port protocol=&amp;#34;tcp&amp;#34; port=&amp;#34;3000&amp;#34;/&amp;gt; &amp;lt;/zone&amp;gt; ポート3000は確認が済んだら削除して閉じます。
設定変更したらサービスを再起動します。
# systemctl restart firewalld PostgreSQL インストール # yum -y install postgresql-server postgresql-devel 初期化処理 # postgresql-setup initdb サービス起動&amp;amp;自動起動設定 # systemctl start postgresql.</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>CentOS7 + Rails5 + Nginx + puma + PostgreSQLで本番環境を構築したときの作業履歴とメモ。サーバーはさくらのクラウドです。</p>
<h2 id="初期設定">初期設定</h2>
<p>Rails本番環境とは直接関係ない項目もありますが下準備&amp;最低限必要な設定として行いました。</p>
<h3 id="一般ユーザーの作成sudossh接続設定公開鍵認証">一般ユーザーの作成&amp;sudo&amp;ssh接続設定（公開鍵認証）</h3>
<p><a href="https://help.sakura.ad.jp/hc/ja/articles/206208181">【さくらのVPS】サーバの初期設定ガイド</a></p>
<p>を参考に設定しました。</p>
<h3 id="yum-cronによるパッケージの自動更新">yum-cronによるパッケージの自動更新</h3>
<h4 id="インストール">インストール</h4>
<pre tabindex="0"><code># yum -y install yum-cron
</code></pre><h4 id="設定">設定</h4>
<pre tabindex="0"><code># vi /etc/yum/yum-cron.conf
</code></pre><p>自動更新を有効に設定</p>
<pre tabindex="0"><code>apply_updates = yes
</code></pre><h4 id="サービス起動自動起動設定">サービス起動&amp;自動起動設定</h4>
<pre tabindex="0"><code># systemctl start yum-cron
# systemctl enable yum-cron
</code></pre><h3 id="firewall設定">Firewall設定</h3>
<p>httpのポートを開けます。また、作業途中の確認用にポート3000も開けます。</p>
<pre tabindex="0"><code># vi /etc/firewalld/zones/public.xml
</code></pre><pre tabindex="0"><code>&lt;zone&gt;
  …省略
  &lt;service name=&#34;http&#34;/&gt;
  &lt;port protocol=&#34;tcp&#34; port=&#34;3000&#34;/&gt;
&lt;/zone&gt;
</code></pre><p>ポート3000は確認が済んだら削除して閉じます。</p>
<p>設定変更したらサービスを再起動します。</p>
<pre tabindex="0"><code># systemctl restart firewalld
</code></pre><h2 id="postgresql">PostgreSQL</h2>
<h3 id="インストール-1">インストール</h3>
<pre tabindex="0"><code># yum -y install postgresql-server postgresql-devel
</code></pre><h3 id="初期化処理">初期化処理</h3>
<pre tabindex="0"><code># postgresql-setup initdb
</code></pre><h3 id="サービス起動自動起動設定-1">サービス起動&amp;自動起動設定</h3>
<pre tabindex="0"><code># systemctl start postgresql.service
# systemctl enable postgresql.service
</code></pre><h3 id="パスワード認証に変更">パスワード認証に変更</h3>
<pre tabindex="0"><code># vi /var/lib/pgsql/data/pg_hba.conf
</code></pre><pre tabindex="0"><code>local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5
</code></pre><p>に変更します。</p>
<h3 id="postgresユーザのdb接続パスワード設定">postgresユーザのDB接続パスワード設定</h3>
<pre tabindex="0"><code># su - postgres
$ psql -U postgres
postgres=# ALTER USER postgres encrypted password &#39;パスワード&#39;;
postgres=# \q
$ exit
</code></pre><h3 id="サービス再起動">サービス再起動</h3>
<pre tabindex="0"><code># systemctl restart postgresql.service
</code></pre><h3 id="ユーザー作成">ユーザー作成</h3>
<pre tabindex="0"><code># su - postgres
$ createuser -P ユーザー名
パスワード入力
</code></pre><h3 id="db作成">DB作成</h3>
<p>作成したユーザーをオーナーとしたDBを作成します。</p>
<pre tabindex="0"><code>$ psql -U postgres
postgres=# create database DB名 owner ユーザー名;
</code></pre><h2 id="rbenv">rbenv</h2>
<h3 id="必要パッケージのインストール">必要パッケージのインストール</h3>
<pre tabindex="0"><code># yum install -y git gcc gcc-c++ openssl-devel readline-devel
</code></pre><h3 id="インストール-2">インストール</h3>
<p>初期設定で作成した一般ユーザーのホームディレクトリで行います。</p>
<pre tabindex="0"><code>$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
</code></pre><pre tabindex="0"><code>$ echo &#39;export PATH=&#34;$HOME/.rbenv/bin:$PATH&#34;&#39; &gt;&gt; ~/.bash_profile
$ echo &#39;eval &#34;$(rbenv init -)&#34;&#39; &gt;&gt; ~/.bash_profile
$ source ~/.bash_profile 
</code></pre><pre tabindex="0"><code>$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
</code></pre><h3 id="rubyインストール">rubyインストール</h3>
<pre tabindex="0"><code>$ rbenv install 2.4.1
$ rbenv global 2.4.1
$ rbenv rehash
</code></pre><h3 id="bundlerインストール">bundlerインストール</h3>
<pre tabindex="0"><code>$ gem install bundler
</code></pre><h2 id="railsアプリのデプロイ">Railsアプリのデプロイ</h2>
<p>Railsアプリのgitリポジトリがある前提です。</p>
<p>初期設定で作成した一般ユーザーのホームディレクトリで行います。</p>
<h3 id="git-clone">git clone</h3>
<pre tabindex="0"><code>$ git clone リポジトリURL
$ cd リポジトリ名
</code></pre><h3 id="パッケージインストール">パッケージインストール</h3>
<pre tabindex="0"><code>$ bundle install --without development test
</code></pre><h3 id="envファイル作成">.envファイル作成</h3>
<pre tabindex="0"><code>$ vi .env
</code></pre><p>DB接続情報やその他アプリに必要な情報を設定します。</p>
<pre tabindex="0"><code>RAILS_DATABASE_USERNAME=&#34;ユーザー名&#34;
RAILS_DATABASE_PASSWORD=&#34;パスワード&#34;
</code></pre><p>DB名やホスト、ポートは<code>config/database.yml</code> にデフォルト値として設定しています。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">production</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">adapter</span>: <span style="color:#ae81ff">postgresql</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">encoding</span>: <span style="color:#ae81ff">unicode</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">database</span>: <span style="color:#ae81ff">&lt;%= ENV[&#39;RAILS_DATABASE&#39;] || &#39;DB名&#39; %&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">username</span>: <span style="color:#ae81ff">&lt;%= ENV[&#39;RAILS_DATABASE_USERNAME&#39;] %&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">password</span>: <span style="color:#ae81ff">&lt;%= ENV[&#39;RAILS_DATABASE_PASSWORD&#39;] %&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">host</span>: <span style="color:#ae81ff">&lt;%= ENV[&#39;RAILS_DATABASE_HOST&#39;] || &#39;localhost&#39; %&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">port</span>: <span style="color:#ae81ff">&lt;%= ENV[&#39;RAILS_DATABASE_PORT&#39;] || &#39;5432&#39; %&gt;</span>
</span></span></code></pre></div><h3 id="マイグレーションアセットプリコンパイル">マイグレーション&amp;アセットプリコンパイル</h3>
<pre tabindex="0"><code>$ RAILS_ENV=production bundle exec rails db:migrate
$ RAILS_ENV=production bundle exec rails assets:precompile
</code></pre><h3 id="railsサーバー起動手動">Railsサーバー起動（手動）</h3>
<pre tabindex="0"><code>$ SECRET_KEY_BASE=$(rake secret) RAILS_SERVE_STATIC_FILES=true RAILS_ENV=production puma -w 2
</code></pre><p>ブラウザから<code>サーバー名:3000</code> に接続できることを確認します。確認できたらCtrl + cでサーバーを停止します。また、Firewall設定でポート3000を閉じます。</p>
<p>途中で</p>
<pre tabindex="0"><code>Bundler::GemRequireError: There was an error while trying to load the gem &#39;uglifier&#39;.
</code></pre><p>のエラーが出たのでGemfileを編集して<code>therubyracer</code> を使用するように変更したら解消されました。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span>gem <span style="color:#e6db74">&#39;therubyracer&#39;</span>, <span style="color:#e6db74">platforms</span>: <span style="color:#e6db74">:ruby</span>
</span></span></code></pre></div><p>Node.jsがインストールされていない環境で発生するようです。</p>
<h3 id="自動起動設定">自動起動設定</h3>
<pre tabindex="0"><code># vi /etc/systemd/system/puma.service
</code></pre><pre tabindex="0"><code>[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
Type=simple
User=webstaff
WorkingDirectory=/home/ユーザー名/リポジトリ名
Environment=&#34;RAILS_ENV=production&#34;
Environment=&#34;RAILS_SERVE_STATIC_FILES=true&#34;
Environment=&#34;PORT=3000&#34;
ExecStart=/home/ユーザー名/.rbenv/shims/bundle exec puma -C config/puma.rb
TimeoutSec=15
Restart=always

[Install]
WantedBy=multi-user.target
</code></pre><p>.envに<code>SECRET_KEY_BASE</code> を追加します。</p>
<pre tabindex="0"><code>$ vi /home/ユーザー名/リポジトリ名/.env
</code></pre><p>値はプロジェクトルートディレクトリで以下のコマンドの実行結果を使います。</p>
<pre tabindex="0"><code>$ rake secret
</code></pre><p>最後にサービス起動と自動起動設定を行います。</p>
<pre tabindex="0"><code># cd /etc/systemd/system
# systemctl start puma.service
# systemctl enable puma.service
</code></pre><h2 id="nginx">Nginx</h2>
<h3 id="インストール-3">インストール</h3>
<pre tabindex="0"><code># vi /etc/yum.repos.d/nginx.repo
</code></pre><pre tabindex="0"><code>[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1
</code></pre><pre tabindex="0"><code># yum install -y nginx
</code></pre><h3 id="サービス起動自動起動設定-2">サービス起動&amp;自動起動設定</h3>
<pre tabindex="0"><code># systemctl start nginx
# systemctl enable nginx
</code></pre><p>ブラウザからサーバー名にアクセスできることを確認します。</p>
<h3 id="所有者変更">所有者変更</h3>
<p>Railsアプリのファイルは初期設定で作成した一般ユーザーのホームディレクトリ配下にありますので、nginxがアクセスできるように作成した一般ユーザーで実行されるようにします。</p>
<pre tabindex="0"><code># vi /etc/nginx/nginx.conf
</code></pre><pre tabindex="0"><code>user ユーザー名;
</code></pre><p>に変更します。また、ログファイルを格納するディレクトリの所有者を変更します。</p>
<pre tabindex="0"><code># chown ユーザー名 /var/log/nginx
</code></pre><p>logrotateの設定を変更します。</p>
<pre tabindex="0"><code># vi /etc/logrotate.d/nginx
</code></pre><pre tabindex="0"><code>create 640 ユーザー名 adm
</code></pre><h3 id="リバースプロキシ設定">リバースプロキシ設定</h3>
<pre tabindex="0"><code># vi /etc/nginx/conf.d/サーバー名など任意の名前.conf
</code></pre><pre tabindex="0"><code>server {
    listen 80;
    server_name サーバー名;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_max_temp_file_size 0;
    location / {
        proxy_pass http://localhost:3000;
    }
}
</code></pre><p>最後にサービスを再起動します。</p>
<pre tabindex="0"><code># systemctl restart nginx
</code></pre>]]></content>
        </item>
        
        <item>
            <title>マストドンインスタンスをカスタマイズ(Pawooのお知らせ機能を実装する)</title>
            <link>https://eza-s.com/blog/archives/162/</link>
            <pubDate>Wed, 26 Jul 2017 03:15:41 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/162/</guid>
            <description>はじめに マストドンはオープンソースソフトウェアです。公開されているソースコードを使って自分でマストドンインスタンスを立てるのはもちろん、必要に応じてカスタマイズすることも自由です。また、それぞれのインスタンスでカスタマイズしたソースコードも公開されているので使ってみたい機能を移植することも可能です。
今回はPawooに実装されているお知らせ機能（赤枠の部分）を実装しました。
実装 前置きだけになってしまってアレなのですが、今回実装した内容もGitHubで公開しています。詳しくは↓
https://github.com/mimumemo/mastodon/pull/1/files</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>マストドンはオープンソースソフトウェアです。公開されているソースコードを使って自分でマストドンインスタンスを立てるのはもちろん、必要に応じてカスタマイズすることも自由です。また、それぞれのインスタンスでカスタマイズしたソースコードも公開されているので使ってみたい機能を移植することも可能です。</p>
<p>今回はPawooに実装されているお知らせ機能（赤枠の部分）を実装しました。</p>
<p><img src="https://eza-s.com/blog/wp-content/uploads/2017/07/pawoo.net-web-getting-startediPhone-6-Plus-169x300.png" alt="お知らせ"></p>
<h2 id="実装">実装</h2>
<p>前置きだけになってしまってアレなのですが、今回実装した内容もGitHubで公開しています。詳しくは↓</p>
<p><a href="https://github.com/mimumemo/mastodon/pull/1/files">https://github.com/mimumemo/mastodon/pull/1/files</a></p>
]]></content>
        </item>
        
        <item>
            <title>Railsで多対多のつながりのあるデータをチェックボックスとしてformに表示する</title>
            <link>https://eza-s.com/blog/archives/156/</link>
            <pubDate>Sun, 09 Jul 2017 09:25:37 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/156/</guid>
            <description>はじめに 例えばアンケートなんかで「興味のある事にチェックしてください（複数可）」のようなフォームがあった場合に、アンケートテーブルと興味のある事テーブルを連携させるやり方について。railsではcollection_check_boxes というヘルパーを使うと簡潔に書くことができます。
モデル アンケート（Questionnaire）と興味のある事（Hobby）にアソシエーションを設定します。中間テーブルとしてhobby_questionnaires を使用するhas_many :through を指定しています。
# app/models/questionnaire.rb class Questionnaire &amp;lt; ActiveRecord::Base has_many :hobby_questionnaires has_many :hobbies, :through =&amp;gt; :hobby_questionnaires end # app/models/hobby.rb class Hobby &amp;lt; ActiveRecord::Base has_many :hobby_questionnaires has_many :questionnaries, :through =&amp;gt; :hobby_questionnaires end ビュー # app/views/questionnaries/_form.html.erb ・・・省略 &amp;lt;div class=&amp;#34;form-group&amp;#34;&amp;gt; &amp;lt;%= form.label :hobbies, class: &amp;#39;col-sm-2 control-label&amp;#39; %&amp;gt; &amp;lt;div class=&amp;#34;col-sm-10&amp;#34;&amp;gt; &amp;lt;div class=&amp;#34;checkbox&amp;#34;&amp;gt; &amp;lt;%= collection_check_boxes(:questionnarie, :hobby_ids, Hobby.all, :id, :name) do |b| %&amp;gt; &amp;lt;%= b.label { b.check_box + b.text } %&amp;gt; &amp;lt;% end %&amp;gt; &amp;lt;/div&amp;gt; &amp;lt;/div&amp;gt; &amp;lt;/div&amp;gt; コントローラー ストロングパラメーターに指定を追加します。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>例えばアンケートなんかで「興味のある事にチェックしてください（複数可）」のようなフォームがあった場合に、アンケートテーブルと興味のある事テーブルを連携させるやり方について。railsでは<code>collection_check_boxes</code> というヘルパーを使うと簡潔に書くことができます。</p>
<h2 id="モデル">モデル</h2>
<p>アンケート（Questionnaire）と興味のある事（Hobby）にアソシエーションを設定します。中間テーブルとして<code>hobby_questionnaires</code> を使用する<code>has_many :through</code> を指定しています。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># app/models/questionnaire.rb</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Questionnaire</span> <span style="color:#f92672">&lt;</span> <span style="color:#66d9ef">ActiveRecord</span><span style="color:#f92672">::</span><span style="color:#66d9ef">Base</span>
</span></span><span style="display:flex;"><span>  has_many <span style="color:#e6db74">:hobby_questionnaires</span>
</span></span><span style="display:flex;"><span>  has_many <span style="color:#e6db74">:hobbies</span>, <span style="color:#e6db74">:through</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">:hobby_questionnaires</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># app/models/hobby.rb</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Hobby</span> <span style="color:#f92672">&lt;</span> <span style="color:#66d9ef">ActiveRecord</span><span style="color:#f92672">::</span><span style="color:#66d9ef">Base</span>
</span></span><span style="display:flex;"><span>  has_many <span style="color:#e6db74">:hobby_questionnaires</span>
</span></span><span style="display:flex;"><span>  has_many <span style="color:#e6db74">:questionnaries</span>, <span style="color:#e6db74">:through</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">:hobby_questionnaires</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div><h2 id="ビュー">ビュー</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># app/views/questionnaries/_form.html.erb</span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">・・・省略</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;</span>div class<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;</span><span style="color:#e6db74">%= form.label :hobbies, class: &#39;col-sm-2 control-label&#39; %&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  &lt;div class=</span><span style="color:#e6db74">&#34;col-sm-10&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span>div class<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;checkbox&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;</span><span style="color:#e6db74">%= collection_check_boxes(:questionnarie, :hobby_ids, Hobby.all, :id, :name) do |b| %&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        &lt;%=</span> b<span style="color:#f92672">.</span>label { b<span style="color:#f92672">.</span>check_box <span style="color:#f92672">+</span> b<span style="color:#f92672">.</span>text } <span style="color:#e6db74">%&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">      &lt;% end %&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#e6db74">/div&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  &lt;/</span>div<span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;</span><span style="color:#e6db74">/div&gt;
</span></span></span></code></pre></div><h2 id="コントローラー">コントローラー</h2>
<p>ストロングパラメーターに指定を追加します。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># app/controllers/questionnaries_controller.rb</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">QuestionnariesController</span> <span style="color:#f92672">&lt;</span> <span style="color:#66d9ef">ApplicationController</span>
</span></span><span style="display:flex;"><span>  <span style="color:#960050;background-color:#1e0010">・・・省略</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">post_params</span>
</span></span><span style="display:flex;"><span>      params<span style="color:#f92672">.</span>require(<span style="color:#e6db74">:instance</span>)<span style="color:#f92672">.</span>permit(<span style="color:#960050;background-color:#1e0010">・・・省略</span>, {<span style="color:#e6db74">:hobby_ids</span> <span style="color:#f92672">=&gt;</span> <span style="color:#f92672">[]</span>})
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">end</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>マストドンをv1.2.2→v1.4.6にアップデートした時の作業メモ</title>
            <link>https://eza-s.com/blog/archives/143/</link>
            <pubDate>Mon, 26 Jun 2017 09:55:27 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/143/</guid>
            <description>はじめに マストドンインスタンスを立ててからアップデートをどのタイミングで行うかについて、しばらく様子を見ていたのですが、v1.4系になって色々機能が追加されたのを使いたいということでアップデートすることになりました。
Vagrantなローカル環境で検証した時の作業メモです。
アップデートするのに必要な作業はReleases · tootsuite/mastodonを遡って確認しました。
パッケージの追加 $ sudo apt-get install pkg-config libprotobuf-dev protobuf-compiler -y Node.jsのアップデート サポートするNode.jsのバージョンが6以降となったのでアップデートします。
$ sudo npm install n -g $ sudo n stable $ sudo ln -sf /usr/local/bin/node /usr/bin/node v1.4.6をマージ このインスタンスでは、画像を差し替えるなど本家のソースコードを改変している箇所があります。なので本家のソースコードをマージします。origin はこのインスタンスのリポジトリを登録しているのでupstream に本家のリポジトリを登録します。このインスタンスのブランチはdevelop です。
$ git remote add upstream https://github.com/tootsuite/mastodon.git $ git checkout -b master origin/master $ git fetch upstream $ git merge upstream/master $ git checkout -b v1.4.6 v1.4.6 $ git checkout develop $ git merge v1.</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>マストドンインスタンスを立ててからアップデートをどのタイミングで行うかについて、しばらく様子を見ていたのですが、v1.4系になって色々機能が追加されたのを使いたいということでアップデートすることになりました。</p>
<p><a href="https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Vagrant-guide.md">Vagrantなローカル環境</a>で検証した時の作業メモです。</p>
<p>アップデートするのに必要な作業は<a href="https://github.com/tootsuite/mastodon/releases">Releases · tootsuite/mastodon</a>を遡って確認しました。</p>
<h2 id="パッケージの追加">パッケージの追加</h2>
<pre tabindex="0"><code>$ sudo apt-get install pkg-config libprotobuf-dev protobuf-compiler -y
</code></pre><h2 id="nodejsのアップデート">Node.jsのアップデート</h2>
<p>サポートするNode.jsのバージョンが6以降となったのでアップデートします。</p>
<pre tabindex="0"><code>$ sudo npm install n -g
$ sudo n stable
$ sudo ln -sf /usr/local/bin/node /usr/bin/node
</code></pre><h2 id="v146をマージ">v1.4.6をマージ</h2>
<p>このインスタンスでは、画像を差し替えるなど本家のソースコードを改変している箇所があります。なので本家のソースコードをマージします。<code>origin</code> はこのインスタンスのリポジトリを登録しているので<code>upstream</code> に本家のリポジトリを登録します。このインスタンスのブランチは<code>develop</code> です。</p>
<pre tabindex="0"><code>$ git remote add upstream https://github.com/tootsuite/mastodon.git
$ git checkout -b master origin/master
$ git fetch upstream
$ git merge upstream/master
$ git checkout -b v1.4.6 v1.4.6
$ git checkout develop
$ git merge v1.4.6
</code></pre><p>ソースコードを改変した箇所でコンフリクトしたので修正します。また、変更内容を<code>origin</code> にpushして本番環境ではpullします。</p>
<h2 id="アップデート">アップデート</h2>
<pre tabindex="0"><code>$ bundle install
$ yarn install
$ bundle exec rails mastodon:maintenance:prepare_for_foreign_keys
$ bundle exec rails db:migrate
$ bundle exec rails assets:precompile
$ bundle exec rails r Rails.cache.clear
</code></pre><p>本番環境では<code>bundle exec</code> のところに<code>RAILS_ENV=production</code> が入ります。</p>
<h2 id="サービス起動">サービス起動</h2>
<p>作業前にサービスを停止していたので起動します。</p>
<pre tabindex="0"><code>$ foreman start
</code></pre><h2 id="動作確認">動作確認</h2>
<p>動作確認をしたところ、お気に入りが表示されない不具合が発生しました。</p>
<p><a href="https://github.com/tootsuite/mastodon/issues/3944">本家のissue</a>に同様の不具合が挙がっていて解決法も示されていました。<code>v1.4.6</code> タグではなく<code>master</code> ブランチで作業を行えば解決できるみたいなので<code>master</code> ブランチをマージしてアップデートコマンドをやり直して動作確認できました。</p>
<pre tabindex="0"><code>$ bundle install
$ yarn install
$ bundle exec rails db:migrate
$ bundle exec rails assets:precompile
</code></pre>]]></content>
        </item>
        
        <item>
            <title>マストドンでユーザ数増加に伴った設定変更まとめ</title>
            <link>https://eza-s.com/blog/archives/136/</link>
            <pubDate>Fri, 26 May 2017 05:52:21 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/136/</guid>
            <description>はじめに 頼まれて立てたマストドンインスタンスのユーザ数が想像してたよりも多く（作業当時2000人ぐらい）、デフォルトの設定だと繋がりにくくなったりしたので対応した内容のまとめです。
インスタンスはさくらのクラウドのスタートアップスクリプト「Mastodon」を使って作成しました。
500エラー対策 混雑時に500エラーが発生してページや画像が表示されない、トゥートやブースト、お気に入りができない、といった現象が発生していました。
nginxのerror_logを見ると
2017/04/24 13:39:48 [crit] 30177#0: accept4() failed (24: Too many open files) のように Too many open files のエラーが出ていました。
https://blog.be-dama.com/2016/08/31/centos7_nginx_too-many-open-files/
を参考に設定を変更しました。
また、別のエラーで
2017/04/24 21:20:26 [alert] 14304#0: 1024 worker_connections are not enough というエラーが出ていました。
/etc/nginx/nginx.conf
events { worker_connections 2048; } 1024 =&amp;gt; 2048 にしました。
Sidekiqでキューが待機状態であふれる マストドンではSidekiqを使って非同期処理を実行していますが、混雑時にキューがあふれてしまい、トゥートの反映に時間がかかったりしていました。
/etc/systemd/system/mastodon-sidekiq.service
Environment=&amp;#34;DB_POOL=10&amp;#34; ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 10 -q default -q mailers -q pull -q push DB_POOL と sidekiq のスレッド数を5 =&amp;gt; 10にしました。
画像の保存先をS3に変更 サーバーセットアップ時に40GBの容量を選択して、当初の使用率は10%程度だったのですが、あっという間に50%を超えました。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>頼まれて立てたマストドンインスタンスのユーザ数が想像してたよりも多く（作業当時2000人ぐらい）、デフォルトの設定だと繋がりにくくなったりしたので対応した内容のまとめです。</p>
<p>インスタンスは<a href="https://cloud-news.sakura.ad.jp/startup-script/mastodon/">さくらのクラウドのスタートアップスクリプト「Mastodon」</a>を使って作成しました。</p>
<h2 id="500エラー対策">500エラー対策</h2>
<p>混雑時に500エラーが発生してページや画像が表示されない、トゥートやブースト、お気に入りができない、といった現象が発生していました。</p>
<p>nginxのerror_logを見ると</p>
<pre tabindex="0"><code>2017/04/24 13:39:48 [crit] 30177#0: accept4() failed (24: Too many open files)
</code></pre><p>のように Too many open files のエラーが出ていました。</p>
<p><a href="https://blog.be-dama.com/2016/08/31/centos7_nginx_too-many-open-files/">https://blog.be-dama.com/2016/08/31/centos7_nginx_too-many-open-files/</a></p>
<p>を参考に設定を変更しました。</p>
<p>また、別のエラーで</p>
<pre tabindex="0"><code>2017/04/24 21:20:26 [alert] 14304#0: 1024 worker_connections are not enough
</code></pre><p>というエラーが出ていました。</p>
<p>/etc/nginx/nginx.conf</p>
<pre tabindex="0"><code>events {
    worker_connections 2048;
}
</code></pre><p>1024 =&gt; 2048 にしました。</p>
<h2 id="sidekiqでキューが待機状態であふれる">Sidekiqでキューが待機状態であふれる</h2>
<p>マストドンではSidekiqを使って非同期処理を実行していますが、混雑時にキューがあふれてしまい、トゥートの反映に時間がかかったりしていました。</p>
<p>/etc/systemd/system/mastodon-sidekiq.service</p>
<pre tabindex="0"><code>Environment=&#34;DB_POOL=10&#34;
ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 10 -q default -q mailers -q pull -q push
</code></pre><p>DB_POOL と sidekiq のスレッド数を5 =&gt; 10にしました。</p>
<h2 id="画像の保存先をs3に変更">画像の保存先をS3に変更</h2>
<p>サーバーセットアップ時に40GBの容量を選択して、当初の使用率は10%程度だったのですが、あっという間に50%を超えました。</p>
<p><a href="https://hyper-text.org/archives/2017/04/mastodon-instance-with-amazon-s3.shtml">https://hyper-text.org/archives/2017/04/mastodon-instance-with-amazon-s3.shtml</a></p>
<p>を参考にS3に変更しました。</p>
]]></content>
        </item>
        
        <item>
            <title>LaravelのHTTPミドルウェアを使って広告等の効果測定用パラメータを扱う</title>
            <link>https://eza-s.com/blog/archives/131/</link>
            <pubDate>Thu, 27 Apr 2017 09:30:39 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/131/</guid>
            <description>はじめに 会員登録や購入手続きやフォームからの問い合わせ等、何かしらができるWebサイトがあって、複数の外部サイトからリンクされていたとして、どこからの成果なのか判別したい、という要望があります。
外部サイト側でいわゆる広告コードをリンクする際にパラメータとして渡して、それをWebサイト側で保持する、という方法が取られると思います。
その際、外部サイトからリンクされるのはWebサイトのトップページだけとは限らない場合、共通化したいな〜と思いますよね。
LaravelではHTTPミドルウェアという機能を使えばスッキリまとめることができます。
ミドルウェアの定義 artisanコマンドを使ってファイルを生成できます。ファイルはapp/Http/Middleware に生成されます。
$ php artisan make:middleware PrCode ファイルの中は以下になります。
&amp;lt;?php namespace App\Http\Middleware; use Closure; class PrCode { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $pr_code = &amp;#39;pr_code&amp;#39;; if ( ! $request-&amp;gt;input($pr_code)) { return $next($request); } $response = $next($request); $response-&amp;gt;withCookie(cookie($pr_code, $request-&amp;gt;input($pr_code), 0)); return $response; } } リクエストパラメータにpr_code がないか、あってもfalse とみなされる値の場合は何もせず、それ以外の場合はCookieに値をセットしてリクエストのあった画面に遷移します。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>会員登録や購入手続きやフォームからの問い合わせ等、何かしらができるWebサイトがあって、複数の外部サイトからリンクされていたとして、どこからの成果なのか判別したい、という要望があります。</p>
<p>外部サイト側でいわゆる広告コードをリンクする際にパラメータとして渡して、それをWebサイト側で保持する、という方法が取られると思います。</p>
<p>その際、外部サイトからリンクされるのはWebサイトのトップページだけとは限らない場合、共通化したいな〜と思いますよね。</p>
<p>LaravelではHTTPミドルウェアという機能を使えばスッキリまとめることができます。</p>
<h2 id="ミドルウェアの定義">ミドルウェアの定義</h2>
<p>artisanコマンドを使ってファイルを生成できます。ファイルは<code>app/Http/Middleware</code> に生成されます。</p>
<pre tabindex="0"><code>$ php artisan make:middleware PrCode
</code></pre><p>ファイルの中は以下になります。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> <span style="color:#a6e22e">App\Http\Middleware</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Closure</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">PrCode</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    * Handle an incoming request.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    * @param  \Illuminate\Http\Request  $request
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    * @param  \Closure  $next
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    * @return mixed
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">handle</span>($request, <span style="color:#a6e22e">Closure</span> $next)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        $pr_code <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;pr_code&#39;</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> ( <span style="color:#f92672">!</span> $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">input</span>($pr_code)) {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> $next($request);
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        $response <span style="color:#f92672">=</span> $next($request);
</span></span><span style="display:flex;"><span>        $response<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">withCookie</span>(<span style="color:#a6e22e">cookie</span>($pr_code, $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">input</span>($pr_code), <span style="color:#ae81ff">0</span>));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> $response;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>リクエストパラメータに<code>pr_code</code> がないか、あっても<code>false</code> とみなされる値の場合は何もせず、それ以外の場合はCookieに値をセットしてリクエストのあった画面に遷移します。</p>
<p>また、今回のミドルウェアをルーティングで使用するために<code>app/Http/Kernel.php</code> の<code>$routeMiddleware</code> に追加します。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">protected</span> $routeMiddleware <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 省略
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#e6db74">&#39;pr_code&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">\App\Http\Middleware\PrCode</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>];
</span></span></code></pre></div><h2 id="cookieの取り出し削除">Cookieの取り出し・削除</h2>
<p>成果が発生してCookieの値を取り出したい時は、該当するコントローラーにて</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">cookie</span>(<span style="color:#e6db74">&#39;pr_code&#39;</span>);
</span></span></code></pre></div><p>Cookieの値を削除したい時は</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">return</span> <span style="color:#a6e22e">view</span>(<span style="color:#e6db74">&#39;path.to.view&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">withCookie</span>(<span style="color:#a6e22e">cookie</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">forget</span>(<span style="color:#e6db74">&#39;pr_code&#39;</span>));
</span></span></code></pre></div><p><code>pr_code</code> ってベタに書いてるけど実際にはconfig化して<code>Config::get()</code> するなどした方がいいと思います。</p>
<h2 id="ルーティング">ルーティング</h2>
<p>ミドルウェアの適用範囲を<code>app/Http/routes.php</code> で設定します。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">group</span>([<span style="color:#e6db74">&#39;middleware&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;pr_code&#39;</span>], <span style="color:#66d9ef">function</span> () {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// ここに書いたルーティングが対象となります
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>});
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>さくらのクラウドのスクリプト「Mastodon」でインスタンスを立てた後に行った設定</title>
            <link>https://eza-s.com/blog/archives/126/</link>
            <pubDate>Mon, 24 Apr 2017 03:18:44 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/126/</guid>
            <description>追記 スタートアップスクリプト「Mastodon」の更新のお知らせ・旧スクリプトを使用して作成されたインスタンス向けの作業のお願い
スクリプト更新されました。旧スクリプトで作成されたインスタンス向け作業についても案内されています。
はじめに さくらのクラウドのスタートアップスクリプト「Mastodon」の手順でインスタンスを立てた後に気がついて行った設定について。
ちなみにインスタンスを立てたのは2017年4月20日です。
Nginxのlogrotate nginxのログがローテートしたタイミングで書き込まれなくなっていました。nginxがmastodonユーザーで実行されているので/var/log/nginx の所有をmastodonユーザーに変更して/etc/logrotate.d/nginx を以下の内容に変更してローテートされるのを確認しました。
# /etc/logrotate.d/nginx /var/log/nginx/*log { create 0644 mastodon nginx daily rotate 10 missingok ifempty compress sharedscripts postrotate /bin/kill -USR1 `cat /run/nginx.pid 2&amp;gt;/dev/null` 2&amp;gt;/dev/null || true endscript } crontab http://cryks.hateblo.jp/entry/2017/04/22/005755 http://qiita.com/koteitan/items/fadbe900c88481888917
を参考にrake mastodon:daily を1日2回実行するよう設定しました。mastodonユーザーにてcrontab -e した後、以下の内容で保存。
RAILS_ENV=production 15 3,6 * * * cd /home/mastodon/live &amp;amp;&amp;amp; /home/mastodon/.rbenv/shims/bundle exec rake mastodon:daily &amp;gt; /dev/null </description>
            <content type="html"><![CDATA[<h2 id="追記">追記</h2>
<p><a href="http://cloud-news.sakura.ad.jp/2017/04/24/mastodon-startupscript-update/">スタートアップスクリプト「Mastodon」の更新のお知らせ・旧スクリプトを使用して作成されたインスタンス向けの作業のお願い</a></p>
<p>スクリプト更新されました。旧スクリプトで作成されたインスタンス向け作業についても案内されています。</p>
<h2 id="はじめに">はじめに</h2>
<p><a href="http://cloud-news.sakura.ad.jp/startup-script/mastodon/">さくらのクラウドのスタートアップスクリプト「Mastodon」</a>の手順でインスタンスを立てた後に気がついて行った設定について。</p>
<p>ちなみにインスタンスを立てたのは2017年4月20日です。</p>
<h2 id="nginxのlogrotate">Nginxのlogrotate</h2>
<p>nginxのログがローテートしたタイミングで書き込まれなくなっていました。nginxがmastodonユーザーで実行されているので<code>/var/log/nginx</code> の所有をmastodonユーザーに変更して<code>/etc/logrotate.d/nginx</code> を以下の内容に変更してローテートされるのを確認しました。</p>
<pre tabindex="0"><code># /etc/logrotate.d/nginx
/var/log/nginx/*log {
    create 0644 mastodon nginx
    daily
    rotate 10
    missingok
    ifempty
    compress
    sharedscripts
    postrotate
        /bin/kill -USR1 `cat /run/nginx.pid 2&gt;/dev/null` 2&gt;/dev/null || true
    endscript
}
</code></pre><h2 id="crontab">crontab</h2>
<p><a href="http://cryks.hateblo.jp/entry/2017/04/22/005755">http://cryks.hateblo.jp/entry/2017/04/22/005755</a>
<a href="http://qiita.com/koteitan/items/fadbe900c88481888917">http://qiita.com/koteitan/items/fadbe900c88481888917</a></p>
<p>を参考に<code>rake mastodon:daily</code> を1日2回実行するよう設定しました。mastodonユーザーにて<code>crontab -e</code> した後、以下の内容で保存。</p>
<pre tabindex="0"><code>RAILS_ENV=production
15 3,6 * * * cd /home/mastodon/live &amp;&amp; /home/mastodon/.rbenv/shims/bundle exec rake mastodon:daily &gt; /dev/null
</code></pre>]]></content>
        </item>
        
        <item>
            <title>LaravelのEloquent ORMで独自のカラムを定義したい</title>
            <link>https://eza-s.com/blog/archives/120/</link>
            <pubDate>Sun, 16 Apr 2017 06:56:58 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/120/</guid>
            <description>DBに対応するカラムがなく、既存のカラムを加工または判定したものを別名で取り出したい時のやり方について。
今回、郵便番号検索を実装する事になった。データベースには郵便番号データが入っていて、入力された郵便番号を元に都道府県・市区町村名・町域名を取得して入力画面上に表示させたいというもの。都道府県は以下の配列から生成されるドロップダウンとなっているので都道府県名ではなく都道府県コードが欲しいのだけどデータベースには入っていなかった。
[ 1 =&amp;gt; &amp;#39;北海道&amp;#39;, // 省略 47 =&amp;gt; &amp;#39;沖縄&amp;#39;, ] 全国地方公共団体コード（カラム名：jis_code）の先頭2桁が都道府県コードとして使えそうだったので以下のアクセサを作成した。
public function getPrefectureIdAttribute() { return intval(substr($this-&amp;gt;jis_code, 0, 2)); } そしてModelの$appendsプロパティに定義してあげればオッケー。
protected $appends = [&amp;#39;prefecture_id&amp;#39;]; </description>
            <content type="html"><![CDATA[<p>DBに対応するカラムがなく、既存のカラムを加工または判定したものを別名で取り出したい時のやり方について。</p>
<p>今回、郵便番号検索を実装する事になった。データベースには<a href="http://www.post.japanpost.jp/zipcode/dl/readme.html">郵便番号データ</a>が入っていて、入力された郵便番号を元に都道府県・市区町村名・町域名を取得して入力画面上に表示させたいというもの。都道府県は以下の配列から生成されるドロップダウンとなっているので都道府県名ではなく都道府県コードが欲しいのだけどデータベースには入っていなかった。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>[
</span></span><span style="display:flex;"><span>    <span style="color:#ae81ff">1</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;北海道&#39;</span>, 
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 省略
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#ae81ff">47</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;沖縄&#39;</span>,
</span></span><span style="display:flex;"><span>]
</span></span></code></pre></div><p>全国地方公共団体コード（カラム名：jis_code）の先頭2桁が都道府県コードとして使えそうだったので以下のアクセサを作成した。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">getPrefectureIdAttribute</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">intval</span>(<span style="color:#a6e22e">substr</span>($this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">jis_code</span>, <span style="color:#ae81ff">0</span>, <span style="color:#ae81ff">2</span>));
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>そしてModelの$appendsプロパティに定義してあげればオッケー。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">protected</span> $appends <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#39;prefecture_id&#39;</span>];
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>[メモ]LaravelでクエリビルダやORMが生成するSQL文を確認したい</title>
            <link>https://eza-s.com/blog/archives/115/</link>
            <pubDate>Thu, 30 Mar 2017 02:51:38 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/115/</guid>
            <description>開発中とかにクエリビルダやORMが生成するSQL文を確認したい時のやり方。
DB::enableQueryLog(); // ここに処理を書く dd(DB::getQueryLog()); </description>
            <content type="html"><![CDATA[<p>開発中とかにクエリビルダやORMが生成するSQL文を確認したい時のやり方。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">DB</span><span style="color:#f92672">::</span><span style="color:#a6e22e">enableQueryLog</span>();
</span></span><span style="display:flex;"><span><span style="color:#75715e">// ここに処理を書く
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">dd</span>(<span style="color:#a6e22e">DB</span><span style="color:#f92672">::</span><span style="color:#a6e22e">getQueryLog</span>());
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>仮想環境でCSSが正常に読み込まれない</title>
            <link>https://eza-s.com/blog/archives/109/</link>
            <pubDate>Thu, 23 Mar 2017 11:43:51 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/109/</guid>
            <description>VirtualBox + Vagrantなローカル環境で開発をしてて、CSSファイルに変更があったので差し替えたのに反映されないという現象が発生した。CSSファイルは別環境で確認できていたのでファイル自体に問題なさそうで、ブラウザのキャッシュをクリアしても変わらなかった。ブラウザのデベロッパーツールで見てみると、CSSファイルが途中までしか読み込まれていなかった。
調べてみるとNginxの設定でsendfileというのがあり、それが有効だとカーネルでキャッシュされたデータを送信するということで、これが有効になっていたので無効に設定することでCSSファイルの変更内容が反映された。
# nginx.conf sendfile off; ちなみにApacheにも同様の設定があった。
# httpd.conf EnableSendfile off </description>
            <content type="html"><![CDATA[<p>VirtualBox + Vagrantなローカル環境で開発をしてて、CSSファイルに変更があったので差し替えたのに反映されないという現象が発生した。CSSファイルは別環境で確認できていたのでファイル自体に問題なさそうで、ブラウザのキャッシュをクリアしても変わらなかった。ブラウザのデベロッパーツールで見てみると、CSSファイルが途中までしか読み込まれていなかった。</p>
<p>調べてみるとNginxの設定でsendfileというのがあり、それが有効だとカーネルでキャッシュされたデータを送信するということで、これが有効になっていたので無効に設定することでCSSファイルの変更内容が反映された。</p>
<pre tabindex="0"><code># nginx.conf
sendfile off;
</code></pre><p>ちなみにApacheにも同様の設定があった。</p>
<pre tabindex="0"><code># httpd.conf
EnableSendfile off
</code></pre>]]></content>
        </item>
        
        <item>
            <title>Laravel5.3でSNS認証</title>
            <link>https://eza-s.com/blog/archives/103/</link>
            <pubDate>Tue, 14 Feb 2017 02:34:39 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/103/</guid>
            <description>はじめに LaravelでLaravel Socialiteを使ってSNS認証の実装を試してみたときのメモ。
Facebookアプリの作成については省略。
インストール $ composer require laravel/socialite でインストールしようとしたら以下のエラーとなった。
$ composer require laravel/socialite
Using version ^3.0 for laravel/socialite
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- Conclusion: remove laravel/framework v5.3.28
- Conclusion: don&amp;#39;t install laravel/framework v5.3.28
- laravel/socialite v3.0.0 requires illuminate/support ~5.4 -&amp;gt; satisfiable by illuminate/support[v5.4.0, v5.4.9].
- laravel/socialite v3.</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>Laravelで<a href="https://github.com/laravel/socialite">Laravel Socialite</a>を使ってSNS認証の実装を試してみたときのメモ。</p>
<p>Facebookアプリの作成については省略。</p>
<h2 id="インストール">インストール</h2>
<pre tabindex="0"><code>$ composer require laravel/socialite
</code></pre><p>でインストールしようとしたら以下のエラーとなった。</p>
<pre tabindex="0"><code>$ composer require laravel/socialite
Using version ^3.0 for laravel/socialite
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: remove laravel/framework v5.3.28
    - Conclusion: don&#39;t install laravel/framework v5.3.28
    - laravel/socialite v3.0.0 requires illuminate/support ~5.4 -&gt; satisfiable by illuminate/support[v5.4.0, v5.4.9].
    - laravel/socialite v3.0.2 requires illuminate/support ~5.4 -&gt; satisfiable by illuminate/support[v5.4.0, v5.4.9].
    - laravel/socialite v3.0.3 requires illuminate/support ~5.4 -&gt; satisfiable by illuminate/support[v5.4.0, v5.4.9].
    - don&#39;t install illuminate/support v5.4.0|don&#39;t install laravel/framework v5.3.28
    - don&#39;t install illuminate/support v5.4.9|don&#39;t install laravel/framework v5.3.28
    - Installation request for laravel/framework (locked at v5.3.28, required as 5.3.*) -&gt; satisfiable by laravel/framework[v5.3.28].
    - Installation request for laravel/socialite ^3.0 -&gt; satisfiable by laravel/socialite[v3.0.0, v3.0.2, v3.0.3].


Installation failed, reverting ./composer.json to its original content.
</code></pre><p>socialite 3.0.* はlaravel 5.4以上が必要みたいなのでバージョンを指定してインストールした。</p>
<pre tabindex="0"><code>$ composer require laravel/socialite &#34;2.0.*&#34;
</code></pre><h2 id="設定">設定</h2>
<p><code>config/app.php</code> に以下を追加</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#e6db74">&#39;providers&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Other service providers...
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Laravel\Socialite\SocialiteServiceProvider</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>],
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#39;aliases&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Other aliases...
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;Socialite&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">Laravel\Socialite\Facades\Socialite</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>],
</span></span></code></pre></div><p><code>config/services.php</code> に以下を追加</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#e6db74">&#39;facebook&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;client_id&#39;</span>     <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">env</span>(<span style="color:#e6db74">&#39;FACEBOOK_ID&#39;</span>),
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;client_secret&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">env</span>(<span style="color:#e6db74">&#39;FACEBOOK_SECRET&#39;</span>),
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;redirect&#39;</span>      <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">env</span>(<span style="color:#e6db74">&#39;FACEBOOK_CALLBACKURL&#39;</span>),
</span></span><span style="display:flex;"><span>    ],
</span></span></code></pre></div><p>このようにすると実際の値は<code>.env</code> に持たせることができる。</p>
<h2 id="ルーティング">ルーティング</h2>
<p><code>routes/web.php</code> に以下を追加</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// routes/web.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;auth/{provider}&#39;</span>, <span style="color:#e6db74">&#39;Auth\AuthController@redirectToProvider&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;auth/{provider}/callback&#39;</span>, <span style="color:#e6db74">&#39;Auth\AuthController@handleProviderCallback&#39;</span>);
</span></span></code></pre></div><h2 id="コントローラー">コントローラー</h2>
<p><code>app/Http/Controllers/Auth/AuthController.php</code> を作成</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> <span style="color:#a6e22e">App\Http\Controllers\Auth</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Socialite</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">App\Http\Controllers\Controller</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">AuthController</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Controller</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Redirect the user to the Provider authentication page.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return Response
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">redirectToProvider</span>($provider)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">Socialite</span><span style="color:#f92672">::</span><span style="color:#a6e22e">driver</span>($provider)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">redirect</span>();
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Obtain the user information from Provider.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return Response
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">handleProviderCallback</span>($provider)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        $user <span style="color:#f92672">=</span> <span style="color:#a6e22e">Socialite</span><span style="color:#f92672">::</span><span style="color:#a6e22e">driver</span>($provider)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">user</span>();
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">dd</span>($user);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="動作確認">動作確認</h2>
<p>ブラウザから<code>/auth/facebook</code> にアクセスしてFacebookログインできるか確認する。</p>
]]></content>
        </item>
        
        <item>
            <title>Laravel5.3でユーザーと管理者など別々で認証させたい</title>
            <link>https://eza-s.com/blog/archives/98/</link>
            <pubDate>Tue, 07 Feb 2017 02:23:30 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/98/</guid>
            <description>はじめに 例えば何かしらのWebサービスで、サービス利用者としてのユーザーとサービス運営者としての管理者のアカウントをそれぞれ別のテーブルで管理して別々で認証させたい、という時の作業内容についてのメモ。
ユーザー認証 Laravelに用意されているスカフォールドを使う。
$ php artisan make:auth
$ php artisan migrate users テーブルと必要なコントローラー、ビューのファイルが作成される。以下のルーティングが追加される。
$ php artisan route:list
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+
| | GET|HEAD | home | | App\Http\Controllers\HomeController@index | web,auth |
| | POST | login | | App\Http\Controllers\Auth\LoginController@login | web,guest |
| | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web,guest |
| | POST | logout | logout | App\Http\Controllers\Auth\LoginController@logout | web |
| | POST | password/email | | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail | web,guest |
| | POST | password/reset | | App\Http\Controllers\Auth\ResetPasswordController@reset | web,guest |
| | GET|HEAD | password/reset | | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest |
| | GET|HEAD | password/reset/{token} | | App\Http\Controllers\Auth\ResetPasswordController@showResetForm | web,guest |
| | POST | register | | App\Http\Controllers\Auth\RegisterController@register | web,guest |
| | GET|HEAD | register | register | App\Http\Controllers\Auth\RegisterController@showRegistrationForm | web,guest |
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+ 管理者認証 テーブル マイグレーションで管理者用のテーブルを作成する。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>例えば何かしらのWebサービスで、サービス利用者としてのユーザーとサービス運営者としての管理者のアカウントをそれぞれ別のテーブルで管理して別々で認証させたい、という時の作業内容についてのメモ。</p>
<h2 id="ユーザー認証">ユーザー認証</h2>
<p>Laravelに用意されているスカフォールドを使う。</p>
<pre tabindex="0"><code>$ php artisan make:auth
$ php artisan migrate
</code></pre><p><code>users</code> テーブルと必要なコントローラー、ビューのファイルが作成される。以下のルーティングが追加される。</p>
<pre tabindex="0"><code>$ php artisan route:list
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+
| Domain | Method    | URI                          | Name                 | Action                                                                 | Middleware   |
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+
|        | GET|HEAD  | home                         |                      | App\Http\Controllers\HomeController@index                              | web,auth     |
|        | POST      | login                        |                      | App\Http\Controllers\Auth\LoginController@login                        | web,guest    |
|        | GET|HEAD  | login                        | login                | App\Http\Controllers\Auth\LoginController@showLoginForm                | web,guest    |
|        | POST      | logout                       | logout               | App\Http\Controllers\Auth\LoginController@logout                       | web          |
|        | POST      | password/email               |                      | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail  | web,guest    |
|        | POST      | password/reset               |                      | App\Http\Controllers\Auth\ResetPasswordController@reset                | web,guest    |
|        | GET|HEAD  | password/reset               |                      | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest    |
|        | GET|HEAD  | password/reset/{token}       |                      | App\Http\Controllers\Auth\ResetPasswordController@showResetForm        | web,guest    |
|        | POST      | register                     |                      | App\Http\Controllers\Auth\RegisterController@register                  | web,guest    |
|        | GET|HEAD  | register                     | register             | App\Http\Controllers\Auth\RegisterController@showRegistrationForm      | web,guest    |
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+
</code></pre><h2 id="管理者認証">管理者認証</h2>
<h3 id="テーブル">テーブル</h3>
<p>マイグレーションで管理者用のテーブルを作成する。</p>
<pre tabindex="0"><code>$ php artisan make:migration create_admin_users_table
</code></pre><p>今回は<code>users</code> テーブルの内容を元に作成した。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// database/migrations/yyyy_mm_dd_*_create_admin_users_table.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Support\Facades\Schema</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Database\Schema\Blueprint</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Database\Migrations\Migration</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CreateAdminUsersTable</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Migration</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Run the migrations.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return void
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">up</span>()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">Schema</span><span style="color:#f92672">::</span><span style="color:#a6e22e">create</span>(<span style="color:#e6db74">&#39;admin_users&#39;</span>, <span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">Blueprint</span> $table) {
</span></span><span style="display:flex;"><span>            $table<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">increments</span>(<span style="color:#e6db74">&#39;id&#39;</span>);
</span></span><span style="display:flex;"><span>            $table<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">string</span>(<span style="color:#e6db74">&#39;name&#39;</span>);
</span></span><span style="display:flex;"><span>            $table<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">string</span>(<span style="color:#e6db74">&#39;email&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">unique</span>();
</span></span><span style="display:flex;"><span>            $table<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">string</span>(<span style="color:#e6db74">&#39;password&#39;</span>);
</span></span><span style="display:flex;"><span>            $table<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">rememberToken</span>();
</span></span><span style="display:flex;"><span>            $table<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">timestamps</span>();
</span></span><span style="display:flex;"><span>        });
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Reverse the migrations.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return void
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">down</span>()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">Schema</span><span style="color:#f92672">::</span><span style="color:#a6e22e">drop</span>(<span style="color:#e6db74">&#39;admin_users&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><pre tabindex="0"><code>$ php artisan migrate
</code></pre><p><code>admin_users</code> テーブルが作成される。</p>
<h3 id="モデル">モデル</h3>
<p><code>App/User.php</code> をコピーして<code>App/AdminUser.php</code> を作成する。クラス名以外は特に変更点なし。</p>
<h3 id="設定">設定</h3>
<p><code>config/auth.php</code> を以下のように変更する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">return</span> [
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;defaults&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;guard&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;user&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;passwords&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;users&#39;</span>,
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;guards&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;user&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;driver&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;session&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;provider&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;users&#39;</span>,
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;api&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;driver&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;token&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;provider&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;users&#39;</span>,
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;admin&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;driver&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;session&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;provider&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;admin_users&#39;</span>,
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;providers&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;users&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;driver&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;eloquent&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;model&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">App\User</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;admin_users&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;driver&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;eloquent&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;model&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">App\AdminUser</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>,
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;passwords&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;users&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;provider&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;users&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;table&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;password_resets&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;expire&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#ae81ff">60</span>,
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;admin_users&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;provider&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;admin_users&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;table&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;password_resets&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;expire&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#ae81ff">60</span>,
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>];
</span></span></code></pre></div><h3 id="ルーティング">ルーティング</h3>
<p><code>routes/web.php</code> に以下のルーティングを追加する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">group</span>([<span style="color:#e6db74">&#39;prefix&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;admin&#39;</span>], <span style="color:#66d9ef">function</span>() {
</span></span><span style="display:flex;"><span>  $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;login&#39;</span>, <span style="color:#e6db74">&#39;Admin\Auth\LoginController@showLoginForm&#39;</span>);
</span></span><span style="display:flex;"><span>  $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">post</span>(<span style="color:#e6db74">&#39;login&#39;</span>, <span style="color:#e6db74">&#39;Admin\Auth\LoginController@login&#39;</span>);
</span></span><span style="display:flex;"><span>  $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">post</span>(<span style="color:#e6db74">&#39;logout&#39;</span>, <span style="color:#e6db74">&#39;Admin\Auth\LoginController@logout&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">get</span>(<span style="color:#e6db74">&#39;/home&#39;</span>, <span style="color:#e6db74">&#39;Admin\HomeController@index&#39;</span>);
</span></span><span style="display:flex;"><span>});
</span></span></code></pre></div><h3 id="コントローラー">コントローラー</h3>
<p><code>app/Http/Controllers/Auth/LoginController.php</code> を<code>app/Http/Controllers/Admin/Auth/LoginController.php</code> にコピーして以下のように変更する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> <span style="color:#a6e22e">App\Http\Controllers\Admin\Auth</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">App\Http\Controllers\Controller</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Foundation\Auth\AuthenticatesUsers</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Support\Facades\Auth</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">LoginController</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Controller</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">/*
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    |--------------------------------------------------------------------------
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    | Login Controller
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    |--------------------------------------------------------------------------
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    |
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    | This controller handles authenticating users for the application and
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    | redirecting them to your home screen. The controller uses a trait
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    | to conveniently provide its functionality to your applications.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    |
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">    */</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">use</span> <span style="color:#a6e22e">AuthenticatesUsers</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Where to redirect users after login.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @var string
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">protected</span> $redirectTo <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;/admin/home&#39;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Create a new controller instance.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return void
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> __construct()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">middleware</span>(<span style="color:#e6db74">&#39;guest&#39;</span>, [<span style="color:#e6db74">&#39;except&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;logout&#39;</span>]);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Show the application&#39;s login form.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return \Illuminate\Http\Response
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">showLoginForm</span>()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">view</span>(<span style="color:#e6db74">&#39;admin.auth.login&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Get the guard to be used during authentication.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return \Illuminate\Contracts\Auth\StatefulGuard
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">protected</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">guard</span>()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">Auth</span><span style="color:#f92672">::</span><span style="color:#a6e22e">guard</span>(<span style="color:#e6db74">&#39;admin&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><code>app/Http/Controllers/HomeController.php</code> を<code>app/Http/Controllers/Admin/HomeController.php</code> にコピーして以下のように変更する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> <span style="color:#a6e22e">App\Http\Controllers\Admin</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">App\Http\Controllers\Controller</span>;
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Http\Request</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">HomeController</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Controller</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Create a new controller instance.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return void
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> __construct()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">middleware</span>(<span style="color:#e6db74">&#39;auth:admin&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * Show the application dashboard.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     * @return \Illuminate\Http\Response
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">     */</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">index</span>()
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">view</span>(<span style="color:#e6db74">&#39;admin.home&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="ビュー">ビュー</h3>
<p><code>resources/views/auth/login.blade.php</code> を<code>resources/views/admin/auth/login.blade.php</code> にコピーして以下の箇所を変更する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">form</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-horizontal&#34;</span> <span style="color:#a6e22e">role</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form&#34;</span> <span style="color:#a6e22e">method</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;POST&#34;</span> <span style="color:#a6e22e">action</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ url(&#39;/admin/login&#39;) }}&#34;</span><span style="color:#f92672">&gt;</span>
</span></span></code></pre></div><p><code>resources/views/home.blade.php</code> を<code>resources/views/admin/home.blade.php</code> にコピーする。</p>
<h2 id="その他">その他</h2>
<p><code>app/Exceptions/Handler.php</code> の<code>unauthenticated()</code> を以下のように変更する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">protected</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">unauthenticated</span>($request, <span style="color:#a6e22e">AuthenticationException</span> $exception)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">expectsJson</span>()) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">response</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">json</span>([<span style="color:#e6db74">&#39;error&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;Unauthenticated.&#39;</span>], <span style="color:#ae81ff">401</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">in_array</span>(<span style="color:#e6db74">&#39;admin&#39;</span>, $exception<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">guards</span>())) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">redirect</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">guest</span>(<span style="color:#e6db74">&#39;admin/login&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">redirect</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">guest</span>(<span style="color:#e6db74">&#39;login&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="確認">確認</h2>
<p>ユーザーはブラウザから<code>/register</code> にアクセスして登録する。管理者の登録画面は今回用意していないので別途作成する。</p>
<p>ユーザーは<code>/login</code> からログインすると<code>/home</code> に遷移する。未ログイン状態で<code>/home</code> にアクセスすると<code>/login</code> にリダイレクトする。</p>
<p>管理者は<code>/admin/login</code> からログインすると<code>/admin/home</code> に遷移する。未ログイン状態で<code>/admin/home</code> にアクセスすると<code>/admin/login</code> にリダイレクトする。</p>
<p>ユーザーは管理者のログイン画面からはログインできず、管理者もユーザーのログイン画面からはログインできない。</p>
]]></content>
        </item>
        
        <item>
            <title>Laravel5.3でテスト</title>
            <link>https://eza-s.com/blog/archives/90/</link>
            <pubDate>Wed, 01 Feb 2017 03:21:56 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/90/</guid>
            <description>はじめに 前回の実装のテストを書いたのでメモ。LaravelではアプリケーションにHTTPリクエストを送信し、出力内容をチェックしたりフォームに入力したりリンクやボタンをクリックするようなテストを書くことができる。
データベース設定 .env.testing にテスト用データベースの接続設定を書く。
モデルファクトリーの追加 テストを実行する際にあらかじめデータを入れておきたい場合の便利な機能。database/factories/ModelFactory.php に設定を追加する。
$factory-&amp;gt;define(App\Sample::class, function (Faker\Generator $faker) { return [ &amp;#39;name&amp;#39; =&amp;gt; $faker-&amp;gt;name, &amp;#39;email&amp;#39; =&amp;gt; $faker-&amp;gt;unique()-&amp;gt;safeEmail, ]; }); テストから以下のように使用する。
$sample = factory(App\Sample::class)-&amp;gt;create(); $samples = factory(App\Sample::class, 3)-&amp;gt;create(); // 件数を指定して複数生成する $sample = factory(App\Sample::class)-&amp;gt;make(); // DBに保存しない テストファイルの生成と実行 テストファイルの作成
$ php artisan make:test SampleTest 実行
$ ./vendor/bin/phpunit テスト後のデータベースリセット テスト後にデータが残ったままだと色々影響があるのでリセットしたい、というのをLaravelでは用意されているトレイトを使用するだけでできる。
use DatabaseMigrations; // マイグレーションを使用する use DatabaseTransactions; // トランザクションを使用する 今回はマイグレーションを使ってないのでuse DatabaseTransactions; を使用した。
テスト 一覧表示 public function testIndex() { $samples = factory(App\Sample::class, 2)-&amp;gt;create(); // テストデータ2件作成 $this-&amp;gt;visit(&amp;#39;sample&amp;#39;) // 一覧画面にアクセス -&amp;gt;see(&amp;#39;Sample&amp;#39;) // 画面に `Sample` が表示されている -&amp;gt;see($samples[0]-&amp;gt;name)-&amp;gt;see($samples[0]-&amp;gt;email) // テストデータ1件目が表示されている -&amp;gt;see($samples[1]-&amp;gt;name)-&amp;gt;see($samples[1]-&amp;gt;email) // テストデータ2件目が表示されている -&amp;gt;type($samples[0]-&amp;gt;name,&amp;#39;name&amp;#39;) // 検索フォームの名前欄にテストデータ1件目の名前を入力 -&amp;gt;press(&amp;#39;検索&amp;#39;) // 検索ボタンを押す -&amp;gt;see($samples[0]-&amp;gt;name) // テストデータ1件目が表示されている -&amp;gt;dontSee($samples[1]-&amp;gt;name); // テストデータ2件目は表示されない } 新規作成(バリデーションエラー) public function testCreateNG() { $this-&amp;gt;visit(&amp;#39;sample/create&amp;#39;) -&amp;gt;type(&amp;#39;&amp;#39;,&amp;#39;name&amp;#39;) -&amp;gt;type(&amp;#39;&amp;#39;,&amp;#39;email&amp;#39;) -&amp;gt;press(&amp;#39;作成&amp;#39;) -&amp;gt;see(&amp;#39;nameは必須です。&amp;#39;) -&amp;gt;see(&amp;#39;emailは必須です。&amp;#39;); } 新規作成(成功) public function testCreateOK() { $this-&amp;gt;visit(&amp;#39;sample/create&amp;#39;) -&amp;gt;type(&amp;#39;hoge&amp;#39;,&amp;#39;name&amp;#39;) -&amp;gt;type(&amp;#39;hoge@hoge.</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p><a href="http://eza-s.com/blog/archives/56">前回</a>の実装のテストを書いたのでメモ。LaravelではアプリケーションにHTTPリクエストを送信し、出力内容をチェックしたりフォームに入力したりリンクやボタンをクリックするようなテストを書くことができる。</p>
<h2 id="データベース設定">データベース設定</h2>
<p><code>.env.testing</code> にテスト用データベースの接続設定を書く。</p>
<h2 id="モデルファクトリーの追加">モデルファクトリーの追加</h2>
<p>テストを実行する際にあらかじめデータを入れておきたい場合の便利な機能。<code>database/factories/ModelFactory.php</code> に設定を追加する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$factory<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">define</span>(<span style="color:#a6e22e">App\Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>, <span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">Faker\Generator</span> $faker) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;name&#39;</span> <span style="color:#f92672">=&gt;</span> $faker<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;email&#39;</span> <span style="color:#f92672">=&gt;</span> $faker<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">unique</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">safeEmail</span>,
</span></span><span style="display:flex;"><span>    ];
</span></span><span style="display:flex;"><span>});
</span></span></code></pre></div><p>テストから以下のように使用する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">factory</span>(<span style="color:#a6e22e">App\Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">create</span>();
</span></span><span style="display:flex;"><span>$samples <span style="color:#f92672">=</span> <span style="color:#a6e22e">factory</span>(<span style="color:#a6e22e">App\Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>, <span style="color:#ae81ff">3</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">create</span>(); <span style="color:#75715e">// 件数を指定して複数生成する
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>$sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">factory</span>(<span style="color:#a6e22e">App\Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">make</span>(); <span style="color:#75715e">// DBに保存しない
</span></span></span></code></pre></div><h2 id="テストファイルの生成と実行">テストファイルの生成と実行</h2>
<p>テストファイルの作成</p>
<pre tabindex="0"><code>$ php artisan make:test SampleTest
</code></pre><p>実行</p>
<pre tabindex="0"><code>$ ./vendor/bin/phpunit
</code></pre><h2 id="テスト後のデータベースリセット">テスト後のデータベースリセット</h2>
<p>テスト後にデータが残ったままだと色々影響があるのでリセットしたい、というのをLaravelでは用意されているトレイトを使用するだけでできる。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">DatabaseMigrations</span>; <span style="color:#75715e">// マイグレーションを使用する
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">DatabaseTransactions</span>; <span style="color:#75715e">// トランザクションを使用する
</span></span></span></code></pre></div><p>今回はマイグレーションを使ってないので<code>use DatabaseTransactions;</code> を使用した。</p>
<h2 id="テスト">テスト</h2>
<h3 id="一覧表示">一覧表示</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">testIndex</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $samples <span style="color:#f92672">=</span> <span style="color:#a6e22e">factory</span>(<span style="color:#a6e22e">App\Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>, <span style="color:#ae81ff">2</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">create</span>(); <span style="color:#75715e">// テストデータ2件作成
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">visit</span>(<span style="color:#e6db74">&#39;sample&#39;</span>) <span style="color:#75715e">// 一覧画面にアクセス
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>(<span style="color:#e6db74">&#39;Sample&#39;</span>) <span style="color:#75715e">// 画面に `Sample` が表示されている
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($samples[<span style="color:#ae81ff">0</span>]<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($samples[<span style="color:#ae81ff">0</span>]<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">email</span>) <span style="color:#75715e">// テストデータ1件目が表示されている
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($samples[<span style="color:#ae81ff">1</span>]<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($samples[<span style="color:#ae81ff">1</span>]<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">email</span>) <span style="color:#75715e">// テストデータ2件目が表示されている
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">type</span>($samples[<span style="color:#ae81ff">0</span>]<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>,<span style="color:#e6db74">&#39;name&#39;</span>) <span style="color:#75715e">// 検索フォームの名前欄にテストデータ1件目の名前を入力
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">press</span>(<span style="color:#e6db74">&#39;検索&#39;</span>) <span style="color:#75715e">// 検索ボタンを押す
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($samples[<span style="color:#ae81ff">0</span>]<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>) <span style="color:#75715e">// テストデータ1件目が表示されている
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">dontSee</span>($samples[<span style="color:#ae81ff">1</span>]<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>); <span style="color:#75715e">// テストデータ2件目は表示されない
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
</span></span></code></pre></div><h3 id="新規作成バリデーションエラー">新規作成(バリデーションエラー)</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">testCreateNG</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">visit</span>(<span style="color:#e6db74">&#39;sample/create&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">type</span>(<span style="color:#e6db74">&#39;&#39;</span>,<span style="color:#e6db74">&#39;name&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">type</span>(<span style="color:#e6db74">&#39;&#39;</span>,<span style="color:#e6db74">&#39;email&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">press</span>(<span style="color:#e6db74">&#39;作成&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>(<span style="color:#e6db74">&#39;nameは必須です。&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>(<span style="color:#e6db74">&#39;emailは必須です。&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="新規作成成功">新規作成(成功)</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">testCreateOK</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">visit</span>(<span style="color:#e6db74">&#39;sample/create&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">type</span>(<span style="color:#e6db74">&#39;hoge&#39;</span>,<span style="color:#e6db74">&#39;name&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">type</span>(<span style="color:#e6db74">&#39;hoge@hoge.com&#39;</span>,<span style="color:#e6db74">&#39;email&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">press</span>(<span style="color:#e6db74">&#39;作成&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">seePageIs</span>(<span style="color:#e6db74">&#39;/sample&#39;</span>) <span style="color:#75715e">// 一覧画面に遷移した
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>(<span style="color:#e6db74">&#39;hoge&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>(<span style="color:#e6db74">&#39;hoge@hoge.com&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="詳細画面">詳細画面</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">testShow</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">factory</span>(<span style="color:#a6e22e">App\Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">create</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">visit</span>(<span style="color:#e6db74">&#39;sample&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">click</span>($sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>) <span style="color:#75715e">// 一覧画面の名前をクリックすると詳細画面に遷移する
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">seeRouteIs</span>(<span style="color:#e6db74">&#39;sample.show&#39;</span>, [<span style="color:#e6db74">&#39;sample&#39;</span> <span style="color:#f92672">=&gt;</span> $sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">id</span>]) <span style="color:#75715e">// ルーティングから遷移先の妥当性を検証
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="編集">編集</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">testEditOK</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">factory</span>(<span style="color:#a6e22e">App\Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">create</span>();
</span></span><span style="display:flex;"><span>    $new_name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;new_name&#39;</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">visit</span>(<span style="color:#e6db74">&#39;sample&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">click</span>(<span style="color:#e6db74">&#39;編集&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">seeRouteIs</span>(<span style="color:#e6db74">&#39;sample.edit&#39;</span>, [<span style="color:#e6db74">&#39;sample&#39;</span> <span style="color:#f92672">=&gt;</span> $sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">id</span>])
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">type</span>($new_name,<span style="color:#e6db74">&#39;name&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">press</span>(<span style="color:#e6db74">&#39;編集&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">seePageIs</span>(<span style="color:#e6db74">&#39;/sample&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($new_name) <span style="color:#75715e">// 編集後の名前が表示されている
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">dontSee</span>($sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>); <span style="color:#75715e">// 編集前の名前は表示されていない
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
</span></span></code></pre></div><h3 id="削除">削除</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">testDeleteOK</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">factory</span>(<span style="color:#a6e22e">App\Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">class</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">create</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">visit</span>(<span style="color:#e6db74">&#39;sample&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">see</span>($sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">press</span>(<span style="color:#e6db74">&#39;削除&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">seePageIs</span>(<span style="color:#e6db74">&#39;/sample&#39;</span>)
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">dontSee</span>($sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="補足">補足</h2>
<p>今回は画面に表示されているかどうかでデータが登録されていることを確認したけど、</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">seeInDatabase</span>(<span style="color:#e6db74">&#39;samples&#39;</span>, [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;email&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;hoge@example.com&#39;</span>
</span></span><span style="display:flex;"><span>]);
</span></span></code></pre></div><p>とすればデータベースを直接参照することもできる。</p>
]]></content>
        </item>
        
        <item>
            <title>ansibleのバージョンが原因でvagrant provision が失敗</title>
            <link>https://eza-s.com/blog/archives/83/</link>
            <pubDate>Wed, 25 Jan 2017 02:52:30 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/83/</guid>
            <description>あるプロジェクトで開発環境ではsqlite、ステージングと本番環境ではpostgresqlを使っていたんだけど、開発環境では動作したのが動作しなかったり、挙動が異なったりというのが発生したので仮想環境の構成を変更して開発環境でもpostgresqlを使うようにした。
プロジェクトのメンバーに変更した内容を取り込んで
&amp;gt; vagrant provision してもらったが上手くいかないということでログを見せてもらうと
ERROR! no action detected in task. This often indicates a misspelled module name , or incorrect module path. The error appears to have been in &amp;#39;/vagrant/provision/playbook.yml&amp;#39;: line 16, column 7, but maybe elsewhere in the file depending on the exact syntax problem. のようなエラーが。手元の環境では動いているのでファイルが壊れているのかな？と思い見せてもらったけど特に問題なさそう。
調べた結果、今回追加した設定が当該メンバーの仮想環境にインストールされているansibleのバージョンが古くて対応していなかったので、Vagrantfileに
config.vm.provision &amp;#34;ansible_local&amp;#34; do |ansible| ・・・省略 ansible.version = &amp;#34;latest&amp;#34; end を追加して新しいバージョンのansibleがあればアップデートするようにして解決した。</description>
            <content type="html"><![CDATA[<p>あるプロジェクトで開発環境ではsqlite、ステージングと本番環境ではpostgresqlを使っていたんだけど、開発環境では動作したのが動作しなかったり、挙動が異なったりというのが発生したので仮想環境の構成を変更して開発環境でもpostgresqlを使うようにした。</p>
<p>プロジェクトのメンバーに変更した内容を取り込んで</p>
<pre tabindex="0"><code>&gt; vagrant provision
</code></pre><p>してもらったが上手くいかないということでログを見せてもらうと</p>
<pre tabindex="0"><code>ERROR! no action detected in task. This often indicates a misspelled module name
, or incorrect module path.

The error appears to have been in &#39;/vagrant/provision/playbook.yml&#39;: line 16, column 7, 
but maybe elsewhere in the file depending on the exact syntax problem.
</code></pre><p>のようなエラーが。手元の環境では動いているのでファイルが壊れているのかな？と思い見せてもらったけど特に問題なさそう。</p>
<p>調べた結果、今回追加した設定が当該メンバーの仮想環境にインストールされているansibleのバージョンが古くて対応していなかったので、Vagrantfileに</p>
<pre tabindex="0"><code>config.vm.provision &#34;ansible_local&#34; do |ansible|
  ・・・省略
  ansible.version = &#34;latest&#34;
end
</code></pre><p>を追加して新しいバージョンのansibleがあればアップデートするようにして解決した。</p>
]]></content>
        </item>
        
        <item>
            <title>GitHubのWikiにAutodocで生成したAPIドキュメントを追加したい</title>
            <link>https://eza-s.com/blog/archives/79/</link>
            <pubDate>Sun, 22 Jan 2017 05:52:00 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/79/</guid>
            <description>はじめに Autodocとは、rspecを実行した時にドキュメントを生成してくれるツール。
GitHubのWikiを使って画面項目やアクション、使用しているAPIについて簡単にまとめたドキュメントを作成しているプロジェクトがある。最初はAutodocで生成したドキュメントをコピペでWikiの該当箇所に貼り付けていたんだけど、さすがにメンテナンス性が悪すぎるので、Autodocのドキュメントを丸ごとWikiのリポジトリに追加してWiki内でリンクを貼って参照できるようにしようとしたところ以下のような問題が発生した。
現象 Wikiのリポジトリで
/doc/api/v1/hoge/self.md /doc/api/v1/huga/self.md このようなフォルダ構成にしてもGitHubのWiki画面では認識されずhttps://github.com/user-name/project-name/wiki/self となってしまってどちらか片方しか参照できない。
対策 Autodocで以下の設定を追加した。
# spec/support/autodoc.rb Autodoc.configuration.document_path_from_example = -&amp;amp;gt; (example) do example.file_path.gsub(%r&amp;amp;lt;\./spec/[^/]+/(.+)_spec\.rb&amp;amp;gt;, &amp;#39;\1.md&amp;#39;).gsub(%r&amp;amp;lt;/&amp;amp;gt;, &amp;#39;-&amp;#39;) end こうすることで
api-v1-hoge-self.md api-v1-huga-self.md となりGitHubのWiki画面でそれぞれ参照できるようになった。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p><a href="https://github.com/r7kamura/autodoc">Autodoc</a>とは、rspecを実行した時にドキュメントを生成してくれるツール。</p>
<p>GitHubのWikiを使って画面項目やアクション、使用しているAPIについて簡単にまとめたドキュメントを作成しているプロジェクトがある。最初はAutodocで生成したドキュメントをコピペでWikiの該当箇所に貼り付けていたんだけど、さすがにメンテナンス性が悪すぎるので、Autodocのドキュメントを丸ごとWikiのリポジトリに追加してWiki内でリンクを貼って参照できるようにしようとしたところ以下のような問題が発生した。</p>
<h2 id="現象">現象</h2>
<p>Wikiのリポジトリで</p>
<pre tabindex="0"><code>/doc/api/v1/hoge/self.md
/doc/api/v1/huga/self.md
</code></pre><p>このようなフォルダ構成にしてもGitHubのWiki画面では認識されず<code>https://github.com/user-name/project-name/wiki/self</code> となってしまってどちらか片方しか参照できない。</p>
<h2 id="対策">対策</h2>
<p>Autodocで以下の設定を追加した。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-ruby" data-lang="ruby"><span style="display:flex;"><span><span style="color:#75715e"># spec/support/autodoc.rb</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">Autodoc</span><span style="color:#f92672">.</span>configuration<span style="color:#f92672">.</span>document_path_from_example <span style="color:#f92672">=</span> <span style="color:#f92672">-&amp;</span>gt; (example) <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>  example<span style="color:#f92672">.</span>file_path<span style="color:#f92672">.</span>gsub(<span style="color:#e6db74">%r&amp;lt;\./spec/[^/]+/(.+)_spec\.rb&amp;</span>gt;, <span style="color:#e6db74">&#39;\1.md&#39;</span>)<span style="color:#f92672">.</span>gsub(<span style="color:#e6db74">%r&amp;lt;/&amp;</span>gt;, <span style="color:#e6db74">&#39;-&#39;</span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">end</span>
</span></span></code></pre></div><p>こうすることで</p>
<pre tabindex="0"><code>api-v1-hoge-self.md
api-v1-huga-self.md
</code></pre><p>となりGitHubのWiki画面でそれぞれ参照できるようになった。</p>
]]></content>
        </item>
        
        <item>
            <title>Laravelのフォームリクエストバリデーションのuniqueで除外IDを指定する</title>
            <link>https://eza-s.com/blog/archives/73/</link>
            <pubDate>Tue, 17 Jan 2017 03:35:56 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/73/</guid>
            <description>前回軽くふれた内容だけど忘れそう&amp;amp;気になるところがあったので抜粋して少し補足。
Route::resource(&amp;#39;sample&amp;#39;, &amp;#39;SampleController&amp;#39;); というルーティングが前提。
バリデーションのuniqueで指定したIDを除外したい場合Rule クラスのignore メソッドにIDを指定する。コントローラーにバリデーションを記述するのであれば
// app/Http/Controllers/SampleController.php public function update(Request $request, $id) { $this-&amp;gt;validate($request, [ &amp;#39;name&amp;#39; =&amp;gt; &amp;#39;required|max:255&amp;#39;, &amp;#39;email&amp;#39; =&amp;gt; [ &amp;#39;required&amp;#39;, &amp;#39;max:255&amp;#39;, &amp;#39;email&amp;#39;, Rule::unique(&amp;#39;samples&amp;#39;)-&amp;gt;ignore($id), ], ]); // update処理 } のように$id を受け取っているのでそれを指定すればいいけど、フォームリクエストに書くときはどうすればいいのか？結論は
// app/Http/Requests/SampleRequest.php public function rules() { return [ &amp;#39;name&amp;#39; =&amp;gt; &amp;#39;required|max:255&amp;#39;, &amp;#39;email&amp;#39; =&amp;gt; [ &amp;#39;required&amp;#39;, &amp;#39;max:255&amp;#39;, &amp;#39;email&amp;#39;, Rule::unique(&amp;#39;samples&amp;#39;)-&amp;gt;ignore($this-&amp;gt;sample), ], ]; } だったんだけど$this-&amp;gt;sample というのはなんぞ？と思って調べてみた。
FormRequest クラスの継承元であるRequest クラスにあるマジックメソッドにて
// vendor/laravel/framework/src/Illuminate/Http/Request.php /** * Get an input element from the request.</description>
            <content type="html"><![CDATA[<p><a href="http://eza-s.com/blog/2017/01/11/laravel5-3%E4%BD%BF%E3%81%84%E6%96%B9%E3%83%A1%E3%83%A2/">前回</a>軽くふれた内容だけど忘れそう&amp;気になるところがあったので抜粋して少し補足。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#a6e22e">Route</span><span style="color:#f92672">::</span><span style="color:#a6e22e">resource</span>(<span style="color:#e6db74">&#39;sample&#39;</span>, <span style="color:#e6db74">&#39;SampleController&#39;</span>);
</span></span></code></pre></div><p>というルーティングが前提。</p>
<p>バリデーションのuniqueで指定したIDを除外したい場合<code>Rule</code> クラスの<code>ignore</code> メソッドにIDを指定する。コントローラーにバリデーションを記述するのであれば</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Controllers/SampleController.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">update</span>(<span style="color:#a6e22e">Request</span> $request, $id)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">validate</span>($request, [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;name&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;required|max:255&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;email&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;required&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;max:255&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;email&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">Rule</span><span style="color:#f92672">::</span><span style="color:#a6e22e">unique</span>(<span style="color:#e6db74">&#39;samples&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">ignore</span>($id),
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>    ]);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// update処理
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
</span></span></code></pre></div><p>のように<code>$id</code> を受け取っているのでそれを指定すればいいけど、フォームリクエストに書くときはどうすればいいのか？結論は</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Requests/SampleRequest.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">rules</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;name&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;required|max:255&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;email&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;required&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;max:255&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;email&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">Rule</span><span style="color:#f92672">::</span><span style="color:#a6e22e">unique</span>(<span style="color:#e6db74">&#39;samples&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">ignore</span>($this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">sample</span>),
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>    ];
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>だったんだけど<code>$this-&gt;sample</code> というのはなんぞ？と思って調べてみた。</p>
<p><code>FormRequest</code> クラスの継承元である<code>Request</code> クラスにあるマジックメソッドにて</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// vendor/laravel/framework/src/Illuminate/Http/Request.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * Get an input element from the request.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * @param  string  $key
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * @return mixed
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> */</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> __get($key)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">offsetExists</span>($key)) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">offsetGet</span>($key);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">route</span>($key);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>となっていてinputパラメータに該当するものがあればその値を、なければ<code>route</code> メソッドにて</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// vendor/laravel/framework/src/Illuminate/Http/Request.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#e6db74">/**
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * Get the route handling the request.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * @param string|null $param
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> *
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> * @return \Illuminate\Routing\Route|object|string
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74"> */</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">route</span>($param <span style="color:#f92672">=</span> <span style="color:#66d9ef">null</span>)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $route <span style="color:#f92672">=</span> <span style="color:#a6e22e">call_user_func</span>($this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">getRouteResolver</span>());
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">is_null</span>($route) <span style="color:#f92672">||</span> <span style="color:#a6e22e">is_null</span>($param)) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> $route;
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> $route<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">parameter</span>($param);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>ルートパラメータから該当するものを取得するのがわかった。</p>
]]></content>
        </item>
        
        <item>
            <title>Laravel5.3使い方メモ</title>
            <link>https://eza-s.com/blog/archives/56/</link>
            <pubDate>Wed, 11 Jan 2017 03:00:31 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/56/</guid>
            <description>はじめに Laravelの使い方を勉強するため、単一のテーブルに対するCRUDを実装したときのメモ。
インストール Composerが必要なのでインストールしておく。Laravelはターミナルからcomposerコマンドでインストールする。
$ composer create-project --prefer-dist laravel/laravel sample sampleというフォルダが作成される。sampleフォルダにて、
$ php artisan serve とするとビルトインサーバーが起動してhttp://localhost:8000 でアクセスできる。
設定 config/app.php にtimezoneとlocaleを設定。
// config/app.php &amp;#39;timezone&amp;#39; =&amp;gt; &amp;#39;Asia/Tokyo&amp;#39;, &amp;#39;locale&amp;#39; =&amp;gt; &amp;#39;ja&amp;#39;, .env にDB接続情報を設定。
ルーティング routes/web.php にて設定を行う。様々な記述が可能だけど今回はCRUDを実装したかったので、
Route::resource(&amp;#39;sample&amp;#39;, &amp;#39;SampleController&amp;#39;); とした。こうすることで以下のルーティングに対応してくれる。
動詞 URI アクション ルート名 GET /sample index sample.index GET /sample/create create sample.create POST /sample store sample.store GET /sample/{sample} show sample.show GET /sample/{sample}/edit edit sample.edit PUT/PATCH /sample/{sample} update sample.update DELETE /sample/{sample} destroy sample.destroy ちなみに、
$ php artisan route:list で設定されているルーティングを一覧表示することができる。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>Laravelの使い方を勉強するため、単一のテーブルに対するCRUDを実装したときのメモ。</p>
<h2 id="インストール">インストール</h2>
<p><a href="https://getcomposer.org/">Composer</a>が必要なのでインストールしておく。Laravelはターミナルからcomposerコマンドでインストールする。</p>
<pre tabindex="0"><code>$ composer create-project --prefer-dist laravel/laravel sample
</code></pre><p>sampleというフォルダが作成される。sampleフォルダにて、</p>
<pre tabindex="0"><code>$ php artisan serve
</code></pre><p>とするとビルトインサーバーが起動して<code>http://localhost:8000</code> でアクセスできる。</p>
<h2 id="設定">設定</h2>
<p><code>config/app.php</code> にtimezoneとlocaleを設定。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// config/app.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#e6db74">&#39;timezone&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;Asia/Tokyo&#39;</span>,
</span></span><span style="display:flex;"><span><span style="color:#e6db74">&#39;locale&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;ja&#39;</span>,
</span></span></code></pre></div><p><code>.env</code> にDB接続情報を設定。</p>
<h2 id="ルーティング">ルーティング</h2>
<p><code>routes/web.php</code> にて設定を行う。様々な記述が可能だけど今回はCRUDを実装したかったので、</p>
<pre tabindex="0"><code>Route::resource(&#39;sample&#39;, &#39;SampleController&#39;);
</code></pre><p>とした。こうすることで以下のルーティングに対応してくれる。</p>
<table>
<thead>
<tr>
<th>動詞</th>
<th>URI</th>
<th>アクション</th>
<th>ルート名</th>
</tr>
</thead>
<tbody>
<tr>
<td>GET</td>
<td>/sample</td>
<td>index</td>
<td>sample.index</td>
</tr>
<tr>
<td>GET</td>
<td>/sample/create</td>
<td>create</td>
<td>sample.create</td>
</tr>
<tr>
<td>POST</td>
<td>/sample</td>
<td>store</td>
<td>sample.store</td>
</tr>
<tr>
<td>GET</td>
<td>/sample/{sample}</td>
<td>show</td>
<td>sample.show</td>
</tr>
<tr>
<td>GET</td>
<td>/sample/{sample}/edit</td>
<td>edit</td>
<td>sample.edit</td>
</tr>
<tr>
<td>PUT/PATCH</td>
<td>/sample/{sample}</td>
<td>update</td>
<td>sample.update</td>
</tr>
<tr>
<td>DELETE</td>
<td>/sample/{sample}</td>
<td>destroy</td>
<td>sample.destroy</td>
</tr>
</tbody>
</table>
<p>ちなみに、</p>
<pre tabindex="0"><code>$ php artisan route:list
</code></pre><p>で設定されているルーティングを一覧表示することができる。</p>
<h2 id="マイグレーション">マイグレーション</h2>
<p>今回は別のサンプルで使用したテーブルを使いまわしたのでマイグレーションは使用しない。</p>
<h2 id="テンプレート">テンプレート</h2>
<p>ヘッダー／フッターなどの共通部分レイアウトのファイルを<code>resources/views/layouts/master.blade.php</code> に作成した。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">&lt;!</span><span style="color:#a6e22e">DOCTYPE</span> <span style="color:#a6e22e">html</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">html</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">head</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">meta</span> <span style="color:#a6e22e">charset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;utf-8&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">title</span><span style="color:#f92672">&gt;@</span><span style="color:#66d9ef">yield</span>(<span style="color:#e6db74">&#39;title&#39;</span>)<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">title</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">meta</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;viewport&#34;</span> <span style="color:#a6e22e">content</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;width=device-width, initial-scale=1.0&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">link</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text/css&#34;</span> <span style="color:#a6e22e">rel</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;stylesheet&#34;</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/css/bootstrap.min.css&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">script</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js&#34;</span><span style="color:#f92672">&gt;&lt;/</span><span style="color:#a6e22e">script</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">head</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">body</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;!--</span> <span style="color:#a6e22e">共通部分</span> <span style="color:#f92672">--&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;container&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">@</span><span style="color:#66d9ef">yield</span>(<span style="color:#e6db74">&#39;content&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;!--</span> <span style="color:#a6e22e">共通部分</span> <span style="color:#f92672">--&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">script</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/js/bootstrap.min.js&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">body</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">html</span><span style="color:#f92672">&gt;</span>
</span></span></code></pre></div><p>レイアウトに基づいた各ページは</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#66d9ef">extends</span>(<span style="color:#e6db74">&#39;layouts.master&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#a6e22e">section</span>(<span style="color:#e6db74">&#39;title&#39;</span>, <span style="color:#e6db74">&#39;Sample&#39;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#a6e22e">section</span>(<span style="color:#e6db74">&#39;content&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;!--</span> <span style="color:#a6e22e">ページ内容</span> <span style="color:#f92672">--&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#a6e22e">endsection</span>
</span></span></code></pre></div><p>となる。</p>
<h2 id="コントローラー">コントローラー</h2>
<p>artisanコマンドを使えばファイルを生成してくれる。</p>
<pre tabindex="0"><code>$ php artisan make:controller SampleController --resource
</code></pre><p><code>--resouces</code> オプションで前述したルーティング設定に基づいたメソッドが作成される。</p>
<h2 id="モデル">モデル</h2>
<p>こちらもartisanコマンドで生成される。</p>
<pre tabindex="0"><code>$ php artisan make:model Sample
</code></pre><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Sample.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">&lt;?</span><span style="color:#a6e22e">php</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> <span style="color:#a6e22e">App</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">use</span> <span style="color:#a6e22e">Illuminate\Database\Eloquent\Model</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Sample</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Model</span>
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">protected</span> $guarded <span style="color:#f92672">=</span> [];
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><code>protected $guarded = [];</code> を追加した。後述する新規作成で使用する<code>create</code> メソッドで必須となるパラメータで、指定したプロパティはcreateの対象としない（空の配列だと指定なしとなり全プロパティが対象となる）。</p>
<h2 id="一覧表示">一覧表示</h2>
<h3 id="検索フォーム">検索フォーム</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">//　resources/views/sample/index.blade.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">form</span> <span style="color:#a6e22e">method</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;get&#34;</span> <span style="color:#a6e22e">action</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ url(&#39;sample&#39;) }}&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-inline&#34;</span> <span style="color:#a6e22e">role</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">label</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;sr-only&#34;</span> <span style="color:#66d9ef">for</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">名前</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">label</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ request(&#39;name&#39;) }}&#34;</span> <span style="color:#a6e22e">id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-control&#34;</span> <span style="color:#a6e22e">placeholder</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;名前&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">label</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;sr-only&#34;</span> <span style="color:#66d9ef">for</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">メールアドレス</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">label</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ request(&#39;email&#39;) }}&#34;</span> <span style="color:#a6e22e">id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-control&#34;</span> <span style="color:#a6e22e">placeholder</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;メールアドレス&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;submit&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;btn&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;検索&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;btn&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">form</span><span style="color:#f92672">&gt;</span>
</span></span></code></pre></div><p>波括弧で括られた箇所が動的に生成される。それぞれヘルパー関数を使用している。埋め込まれている箇所と関数名から大体想像がつくと思うので説明は省略する。</p>
<h3 id="一覧表示-1">一覧表示</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// resources/views/sample/index.blade.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">@</span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">count</span>($results) <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">table</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;table table-striped table-bordered table-condensed&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">thead</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">tr</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">ID</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">名前</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">メールアドレス</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">編集</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">削除</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">tr</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">thead</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">tbody</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">@</span><span style="color:#66d9ef">foreach</span> ($results <span style="color:#66d9ef">as</span> $result)
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">tr</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>{{ $result<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">id</span> }}<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;&lt;</span><span style="color:#a6e22e">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ route(&#39;sample.show&#39;, [</span><span style="color:#e6db74">$result-&gt;id</span><span style="color:#e6db74">]) }}&#34;</span><span style="color:#f92672">&gt;</span>{{ $result<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span> }}<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">a</span><span style="color:#f92672">&gt;&lt;/</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>{{ $result<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">email</span> }}<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;&lt;</span><span style="color:#a6e22e">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ route(&#39;sample.edit&#39;, [</span><span style="color:#e6db74">$result-&gt;id</span><span style="color:#e6db74">]) }}&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;btn btn-default&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">編集</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">a</span><span style="color:#f92672">&gt;&lt;/</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">form</span> <span style="color:#a6e22e">method</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post&#34;</span> <span style="color:#a6e22e">action</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ route(&#39;sample.destroy&#39;, [</span><span style="color:#e6db74">$result-&gt;id</span><span style="color:#e6db74">]) }}&#34;</span> <span style="color:#a6e22e">style</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;display:inline;&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                            {<span style="color:#f92672">!!</span> <span style="color:#a6e22e">csrf_field</span>() <span style="color:#f92672">!!</span>}
</span></span><span style="display:flex;"><span>                            {{ <span style="color:#a6e22e">method_field</span>(<span style="color:#e6db74">&#39;DELETE&#39;</span>) }}
</span></span><span style="display:flex;"><span>                            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">button</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;submit&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;btn btn-danger&#34;</span> <span style="color:#a6e22e">onclick</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;return confirm(&#39;削除します。よろしいですか？&#39;)&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">削除</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">button</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">form</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">tr</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">@</span><span style="color:#66d9ef">endforeach</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">tbody</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">table</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    {{ $results<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">links</span>() }}
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">p</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">登録されているデータはありません。</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">p</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#66d9ef">endif</span>
</span></span></code></pre></div><p>Bladeテンプレートの制御構文<code>@if</code> や<code>@foreach</code> で条件による出し分けやループの処理を行う。</p>
<p>削除処理では<code>{{ method_field('DELETE') }}</code><!-- raw HTML omitted --> でDELETEメソッドとして扱うことができるようになる。また、<code>{!! csrf_field() !!}</code> でCSRFトークンが埋め込まれる。</p>
<p><code>{{ $results-&gt;links() }}</code> にはページネーションで生成されたページング表示が埋め込まれる。</p>
<h3 id="結果表示">結果表示</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// resources/views/sample/index.blade.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">@</span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">session</span>(<span style="color:#e6db74">&#39;success&#39;</span>))
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;alert alert-success&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">button</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;close&#34;</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">-</span><span style="color:#a6e22e">dismiss</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;alert&#34;</span><span style="color:#f92672">&gt;&amp;</span><span style="color:#a6e22e">times</span>;<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">button</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        {{ <span style="color:#a6e22e">session</span>(<span style="color:#e6db74">&#39;success&#39;</span>) }}
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#66d9ef">endif</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">session</span>(<span style="color:#e6db74">&#39;error&#39;</span>))
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;alert alert-error&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">button</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;close&#34;</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">-</span><span style="color:#a6e22e">dismiss</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;alert&#34;</span><span style="color:#f92672">&gt;&amp;</span><span style="color:#a6e22e">times</span>;<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">button</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        {{ <span style="color:#a6e22e">session</span>(<span style="color:#e6db74">&#39;error&#39;</span>) }}
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#66d9ef">endif</span>
</span></span></code></pre></div><p>新規作成／編集／削除時、実行結果をセッションのフラッシュデータに保持して一覧画面へリダイレクトしてくるので、その表示用。</p>
<h3 id="コントローラー-1">コントローラー</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Controllers/SampleController.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">index</span>(<span style="color:#a6e22e">Request</span> $request)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">query</span>();
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">input</span>(<span style="color:#e6db74">&#39;name&#39;</span>)) {
</span></span><span style="display:flex;"><span>        $sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">where</span>(<span style="color:#e6db74">&#39;name&#39;</span>, <span style="color:#e6db74">&#39;like&#39;</span>, <span style="color:#e6db74">&#39;%&#39;</span><span style="color:#f92672">.</span>$request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">input</span>(<span style="color:#e6db74">&#39;name&#39;</span>)<span style="color:#f92672">.</span><span style="color:#e6db74">&#39;%&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">input</span>(<span style="color:#e6db74">&#39;email&#39;</span>)) {
</span></span><span style="display:flex;"><span>        $sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">where</span>(<span style="color:#e6db74">&#39;email&#39;</span>, <span style="color:#e6db74">&#39;like&#39;</span>, <span style="color:#e6db74">&#39;%&#39;</span><span style="color:#f92672">.</span>$request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">input</span>(<span style="color:#e6db74">&#39;email&#39;</span>)<span style="color:#f92672">.</span><span style="color:#e6db74">&#39;%&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    $results <span style="color:#f92672">=</span> $sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">orderBy</span>(<span style="color:#e6db74">&#39;id&#39;</span>, <span style="color:#e6db74">&#39;desc&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">paginate</span>(<span style="color:#ae81ff">20</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">view</span>(<span style="color:#e6db74">&#39;sample.index&#39;</span>, [<span style="color:#e6db74">&#39;results&#39;</span> <span style="color:#f92672">=&gt;</span> $results]);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>こちらも大体見て想像がつくと思うので説明は省略する。使用するクラスは<code>use</code> で宣言する必要がある。</p>
<h2 id="新規作成">新規作成</h2>
<h3 id="入力フォーム">入力フォーム</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// resources/views/sample/create.blade.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">form</span> <span style="color:#a6e22e">method</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post&#34;</span> <span style="color:#a6e22e">action</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ url(&#39;sample&#39;) }}&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    {<span style="color:#f92672">!!</span> <span style="color:#a6e22e">csrf_field</span>() <span style="color:#f92672">!!</span>}
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">label</span> <span style="color:#66d9ef">for</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-2 control-label&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">名前</span><span style="color:#f92672">*&lt;/</span><span style="color:#a6e22e">label</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-10&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-control&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ old(&#39;name&#39;) }}&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">label</span> <span style="color:#66d9ef">for</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-2 control-label&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">メールアドレス</span><span style="color:#f92672">*&lt;/</span><span style="color:#a6e22e">label</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-10&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span> <span style="color:#a6e22e">id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-control&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ old(&#39;email&#39;) }}&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-offset-2 col-sm-10&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;submit&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;作成&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;btn&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">form</span><span style="color:#f92672">&gt;</span>
</span></span></code></pre></div><p>ヘルパー関数の<code>old</code> でセッションのフラッシュデータとして保持されている入力値を埋め込んでいる。</p>
<h3 id="入力エラー表示">入力エラー表示</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// resources/views/sample/create.blade.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">@</span><span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">count</span>($errors) <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;alert alert-danger&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">a</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;close&#34;</span> <span style="color:#a6e22e">data</span><span style="color:#f92672">-</span><span style="color:#a6e22e">dismiss</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;alert&#34;</span><span style="color:#f92672">&gt;&amp;</span><span style="color:#a6e22e">times</span>;<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">a</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">@</span><span style="color:#66d9ef">foreach</span> ($errors<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">all</span>() <span style="color:#66d9ef">as</span> $error)
</span></span><span style="display:flex;"><span>            {{ $error }}<span style="color:#f92672">&lt;</span><span style="color:#a6e22e">br</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">@</span><span style="color:#66d9ef">endforeach</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">@</span><span style="color:#66d9ef">endif</span>
</span></span></code></pre></div><p>あまり実践的ではない書き方（入力項目の下に個別に表示するのが望ましい）ですいません。</p>
<h3 id="バリデーション">バリデーション</h3>
<p>バリデーションはフォームリクエストとして別ファイルに書くことができる。artisanコマンドを使えばファイルを生成することができる。</p>
<pre tabindex="0"><code>$ php artisan make:request SampleRequest
</code></pre><p><code>authorize</code> <code>rules</code> というメソッドが用意されていて</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Request/SampleRequest.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">authorize</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">true</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>authorizeにはリクエストに対する認証が設定できる。今回は何もしないので<code>true</code> を返すだけ。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Request/SampleRequest.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">rules</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;name&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#e6db74">&#39;required|max:255&#39;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#39;email&#39;</span> <span style="color:#f92672">=&gt;</span> [
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;required&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;max:255&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#39;email&#39;</span>,
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">Rule</span><span style="color:#f92672">::</span><span style="color:#a6e22e">unique</span>(<span style="color:#e6db74">&#39;samples&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">ignore</span>($this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">sample</span>),
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>    ];
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>rulesにバリデーションルールを設定する。<code>Rule::unique('samples')-&gt;ignore($this-&gt;sample),</code> がemailが一意かどうかをチェックして、編集時には自分のIDを除外する、といった指定になる。この指定の仕方がググっても情報がマチマチだったので別記事にまとめておきたい。</p>
<p>この設定を入れておけば入力エラー時にエラー内容を持って元の画面へリダイレクトしてくれる。</p>
<p>日本語版バリデーションメッセージはこちらを使わせていただきました。</p>
<p><a href="https://gist.github.com/syokunin/b37725686b5baf09255b">https://gist.github.com/syokunin/b37725686b5baf09255b</a></p>
<p><code>resources/lang/ja/validation.php</code> に設置。</p>
<h3 id="コントローラー-2">コントローラー</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Controllers/SampleController.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">create</span>()
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">view</span>(<span style="color:#e6db74">&#39;sample.create&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">store</span>(<span style="color:#a6e22e">SampleRequest</span> $request)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">create</span>($request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">only</span>([<span style="color:#e6db74">&#39;name&#39;</span>, <span style="color:#e6db74">&#39;email&#39;</span>]))) {
</span></span><span style="display:flex;"><span>        $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">session</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">flash</span>(<span style="color:#e6db74">&#39;success&#39;</span>, <span style="color:#e6db74">&#39;作成しました。&#39;</span>);
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">session</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">flash</span>(<span style="color:#e6db74">&#39;error&#39;</span>, <span style="color:#e6db74">&#39;作成に失敗しました。&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">redirect</span>(<span style="color:#e6db74">&#39;sample&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><code>SampleRequest $request</code> でフォームリクエストを指定している。</p>
<h2 id="詳細表示">詳細表示</h2>
<h3 id="詳細表示-1">詳細表示</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// resources/views/sample/show.blade.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">table</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;table table-striped table-bordered table-condensed&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">tbody</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">tr</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">名前</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>{{ $result<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span> }}<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">tr</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">tr</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">メールアドレス</span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">th</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>{{ $result<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">email</span> }}<span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">td</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">tr</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">tbody</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">table</span><span style="color:#f92672">&gt;</span>
</span></span></code></pre></div><p>サンプルにつき、詳細といいながら一覧と同じ項目しか出力できていない。</p>
<h3 id="コントローラー-3">コントローラー</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Controllers/SampleController.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">show</span>($id)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">view</span>(<span style="color:#e6db74">&#39;sample.show&#39;</span>, [<span style="color:#e6db74">&#39;result&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">findOrFail</span>($id)]);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><code>Sample::findOrFail($id)</code> は指定IDのデータが見つからなかった場合は404を返す。</p>
<h2 id="編集">編集</h2>
<h3 id="入力フォーム-1">入力フォーム</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// resources/views/sample/edit.blade.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#f92672">&lt;</span><span style="color:#a6e22e">form</span> <span style="color:#a6e22e">method</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;post&#34;</span> <span style="color:#a6e22e">action</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ route(&#39;sample.update&#39;, [</span><span style="color:#e6db74">$result-&gt;id</span><span style="color:#e6db74">]) }}&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    {<span style="color:#f92672">!!</span> <span style="color:#a6e22e">csrf_field</span>() <span style="color:#f92672">!!</span>}
</span></span><span style="display:flex;"><span>    {{ <span style="color:#a6e22e">method_field</span>(<span style="color:#e6db74">&#39;PUT&#39;</span>) }}
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">label</span> <span style="color:#66d9ef">for</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-2 control-label&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">名前</span><span style="color:#f92672">*&lt;/</span><span style="color:#a6e22e">label</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-10&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;name&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-control&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ old(&#39;name&#39;, </span><span style="color:#e6db74">$result-&gt;name</span><span style="color:#e6db74">) }}&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">label</span> <span style="color:#66d9ef">for</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-2 control-label&#34;</span><span style="color:#f92672">&gt;</span><span style="color:#a6e22e">メールアドレス</span><span style="color:#f92672">*&lt;/</span><span style="color:#a6e22e">label</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-10&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text&#34;</span> <span style="color:#a6e22e">name</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span> <span style="color:#a6e22e">id</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;email&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-control&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{{ old(&#39;email&#39;, </span><span style="color:#e6db74">$result-&gt;email</span><span style="color:#e6db74">) }}&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;form-group&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col-sm-offset-2 col-sm-10&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;</span><span style="color:#a6e22e">input</span> <span style="color:#a6e22e">type</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;submit&#34;</span> <span style="color:#a6e22e">value</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;編集&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;btn&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">div</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/</span><span style="color:#a6e22e">form</span><span style="color:#f92672">&gt;</span>
</span></span></code></pre></div><p><code>{{ method_field('PUT') }}</code> でPUTメソッドとして扱うことができるようにしている。また、<code>old</code> の第２引数にDBから取得した値を初期値として設定している。</p>
<h3 id="コントローラー-4">コントローラー</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Controllers/SampleController.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">edit</span>($id)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">view</span>(<span style="color:#e6db74">&#39;sample.edit&#39;</span>, [<span style="color:#e6db74">&#39;result&#39;</span> <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">findOrFail</span>($id)]);
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">update</span>(<span style="color:#a6e22e">SampleRequest</span> $request, $id)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">findOrFail</span>($id);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    $sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">name</span> <span style="color:#f92672">=</span> $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">input</span>(<span style="color:#e6db74">&#39;name&#39;</span>);
</span></span><span style="display:flex;"><span>    $sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">email</span> <span style="color:#f92672">=</span> $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">input</span>(<span style="color:#e6db74">&#39;email&#39;</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">save</span>()) {
</span></span><span style="display:flex;"><span>        $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">session</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">flash</span>(<span style="color:#e6db74">&#39;success&#39;</span>, <span style="color:#e6db74">&#39;編集しました。&#39;</span>);
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">session</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">flash</span>(<span style="color:#e6db74">&#39;error&#39;</span>, <span style="color:#e6db74">&#39;編集に失敗しました。&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">redirect</span>(<span style="color:#e6db74">&#39;sample&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>バリデーションは新規作成と同様。</p>
<h2 id="削除">削除</h2>
<h3 id="削除フォーム">削除フォーム</h3>
<p>一覧画面を参照。</p>
<h3 id="コントローラー-5">コントローラー</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// app/Http/Controllers/SampleController.php
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">destroy</span>(<span style="color:#a6e22e">Request</span> $request, $id)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    $sample <span style="color:#f92672">=</span> <span style="color:#a6e22e">Sample</span><span style="color:#f92672">::</span><span style="color:#a6e22e">findOrFail</span>($id);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> ($sample<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">delete</span>()) {
</span></span><span style="display:flex;"><span>        $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">session</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">flash</span>(<span style="color:#e6db74">&#39;success&#39;</span>, <span style="color:#e6db74">&#39;削除しました。&#39;</span>);
</span></span><span style="display:flex;"><span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        $request<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">session</span>()<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">flash</span>(<span style="color:#e6db74">&#39;error&#39;</span>, <span style="color:#e6db74">&#39;削除に失敗しました。&#39;</span>);
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">redirect</span>(<span style="color:#e6db74">&#39;sample&#39;</span>);
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>説明は省略。</p>
<h2 id="テスト">テスト</h2>
<p>テストはまた別記事にまとめたい。 =&gt; <a href="http://eza-s.com/blog/archives/90">書いた</a>。</p>
]]></content>
        </item>
        
        <item>
            <title>MacBook Air セットアップ内容メモ</title>
            <link>https://eza-s.com/blog/archives/46/</link>
            <pubDate>Sun, 04 Dec 2016 10:08:29 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/46/</guid>
            <description>はじめに 自家用ノートをMacBook Air 11→MacBook Air 13へ買い替えた。移行については移行アシスタントを使えば簡単に移行できるんだけど、SSDを換装するなどしてかれこれ5年ほど使ってて、今となっては不要なアプリケーションとか設定とかが盛りだくさんだったので手動で移行する事にした。今使っている最小限のアプリケーションやデータ、設定を移行させるための作業内容メモ。
ソフトウェアのインストール App Store からインストール One Drive Cot Editor Slack Xcode Web からインストール Firefox Chrome Microsoft Office Atom sync-settings で同期 Cyberduck Android Studio MAMP Insomnia REST Client Homebrew rbenv, ruby-build ruby2.2.4 nodebrew node7.2.0(latest) imagemagick ファイルの同期 One Drive で主なデータを同期 rssキーはUSBメモリで移行 MySQL(MAMP)のデータはアクティブなプロジェクトのものをエクスポート→インポート 設定 Macで隠しファイルを表示する方法 gitのデフォルトユーザー名とメールアドレスを設定 MAMPを使用しているプロジェクトはDocumentRootにシンボリックリンクを貼ったりVirtualHostの設定(hostsも設定)をする MAMPのPHPにパスを通す iOS 証明書をキーチェーンに追加 その他 gitリポジトリのファイルについて、One Driveで同期したからかファイルのパーミッションが違っていて変更された扱いになっていたのでcheckoutで元に戻した 古い方のMacはMac を売却または譲渡する前にを参考に </description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>自家用ノートをMacBook Air 11→MacBook Air 13へ買い替えた。移行については移行アシスタントを使えば簡単に移行できるんだけど、SSDを換装するなどしてかれこれ5年ほど使ってて、今となっては不要なアプリケーションとか設定とかが盛りだくさんだったので手動で移行する事にした。今使っている最小限のアプリケーションやデータ、設定を移行させるための作業内容メモ。</p>
<h2 id="ソフトウェアのインストール">ソフトウェアのインストール</h2>
<h3 id="app-store-からインストール">App Store からインストール</h3>
<ul>
<li>One Drive</li>
<li>Cot Editor</li>
<li>Slack</li>
<li>Xcode</li>
</ul>
<h3 id="web-からインストール">Web からインストール</h3>
<ul>
<li>Firefox</li>
<li>Chrome</li>
<li>Microsoft Office</li>
<li>Atom
<ul>
<li>sync-settings で同期</li>
</ul>
</li>
<li>Cyberduck</li>
<li>Android Studio</li>
<li>MAMP</li>
<li>Insomnia REST Client</li>
<li>Homebrew
<ul>
<li>rbenv, ruby-build
<ul>
<li>ruby2.2.4</li>
</ul>
</li>
<li>nodebrew
<ul>
<li>node7.2.0(latest)</li>
</ul>
</li>
<li>imagemagick</li>
</ul>
</li>
</ul>
<h2 id="ファイルの同期">ファイルの同期</h2>
<ul>
<li>One Drive で主なデータを同期</li>
<li>rssキーはUSBメモリで移行</li>
<li>MySQL(MAMP)のデータはアクティブなプロジェクトのものをエクスポート→インポート</li>
</ul>
<h2 id="設定">設定</h2>
<ul>
<li><a href="http://qiita.com/clutter/items/520efe83b48375048c9f">Macで隠しファイルを表示する方法</a></li>
<li>gitのデフォルトユーザー名とメールアドレスを設定</li>
<li>MAMPを使用しているプロジェクトはDocumentRootにシンボリックリンクを貼ったりVirtualHostの設定(hostsも設定)をする</li>
<li>MAMPのPHPにパスを通す</li>
<li>iOS 証明書をキーチェーンに追加</li>
</ul>
<h2 id="その他">その他</h2>
<ul>
<li>gitリポジトリのファイルについて、One Driveで同期したからかファイルのパーミッションが違っていて変更された扱いになっていたのでcheckoutで元に戻した</li>
<li>古い方のMacは<a href="https://support.apple.com/ja-jp/HT201065">Mac を売却または譲渡する前に</a>を参考に</li>
</ul>
]]></content>
        </item>
        
        <item>
            <title>FuelPHPでサブクエリ</title>
            <link>https://eza-s.com/blog/archives/41/</link>
            <pubDate>Fri, 11 Nov 2016 14:11:52 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/41/</guid>
            <description>ORMを使う場合の例は http://fuelphp.jp/docs/1.9/packages/orm/crud.html#/subqueries を参照。
Query Builderを使う場合、Query_Builder_Select::compile()を使うとサブクエリのSQLを文字列にすることが出来る。
上記URLの例をQuery Builderで作成するとこのような感じ。サブクエリのSQL文字列がクオートやバッククオートで囲まれないようにDB::expr()してあげる。
$sub_query = DB::select(&amp;#39;author&amp;#39;) -&amp;gt;from(&amp;#39;articles&amp;#39;) -&amp;gt;where(&amp;#39;date&amp;#39;, &amp;#39;&amp;amp;lt;&amp;#39;, time()) -&amp;gt;where(&amp;#39;draft&amp;#39;, &amp;#39;=&amp;#39;, 1) -&amp;gt;compile(Database_Connection::instance()); $query = DB::select() -&amp;gt;from(&amp;#39;articles&amp;#39;) -&amp;gt;where(&amp;#39;author&amp;#39;, &amp;#39;=&amp;#39;, 16) -&amp;gt;or_where(&amp;#39;author&amp;#39;, DB::expr($sub_query)); $query-&amp;gt;execute(); </description>
            <content type="html"><![CDATA[<p>ORMを使う場合の例は <a href="http://fuelphp.jp/docs/1.9/packages/orm/crud.html#/subqueries">http://fuelphp.jp/docs/1.9/packages/orm/crud.html#/subqueries</a> を参照。</p>
<p>Query Builderを使う場合、Query_Builder_Select::compile()を使うとサブクエリのSQLを文字列にすることが出来る。</p>
<p>上記URLの例をQuery Builderで作成するとこのような感じ。サブクエリのSQL文字列がクオートやバッククオートで囲まれないようにDB::expr()してあげる。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$sub_query <span style="color:#f92672">=</span> <span style="color:#a6e22e">DB</span><span style="color:#f92672">::</span><span style="color:#a6e22e">select</span>(<span style="color:#e6db74">&#39;author&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">from</span>(<span style="color:#e6db74">&#39;articles&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">where</span>(<span style="color:#e6db74">&#39;date&#39;</span>, <span style="color:#e6db74">&#39;&amp;lt;&#39;</span>, <span style="color:#a6e22e">time</span>())
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">where</span>(<span style="color:#e6db74">&#39;draft&#39;</span>, <span style="color:#e6db74">&#39;=&#39;</span>, <span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">compile</span>(<span style="color:#a6e22e">Database_Connection</span><span style="color:#f92672">::</span><span style="color:#a6e22e">instance</span>());
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$query <span style="color:#f92672">=</span> <span style="color:#a6e22e">DB</span><span style="color:#f92672">::</span><span style="color:#a6e22e">select</span>()
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">from</span>(<span style="color:#e6db74">&#39;articles&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">where</span>(<span style="color:#e6db74">&#39;author&#39;</span>, <span style="color:#e6db74">&#39;=&#39;</span>, <span style="color:#ae81ff">16</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">or_where</span>(<span style="color:#e6db74">&#39;author&#39;</span>, <span style="color:#a6e22e">DB</span><span style="color:#f92672">::</span><span style="color:#a6e22e">expr</span>($sub_query));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$query<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">execute</span>();
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>リモートワークをしててよく聞かれる事その2</title>
            <link>https://eza-s.com/blog/archives/36/</link>
            <pubDate>Sun, 06 Nov 2016 09:17:40 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/36/</guid>
            <description>はじめに リモートワークをしててよく聞かれる事の続き。フリーランスのWebエンジニアとしてリモートワークをしててよく聞かれることについてのまとめ。
オン／オフの切り替え 作業場所として自宅を使う場合、自宅というのは元々生活するスペースなのでそこでどうやってオン／オフを切り替えているのか？というのもよく聞かれる。
理想的なのは仕事部屋として仕事以外のことはしない空間を用意することかもしれない。それは無理でも例えば作業机を用意してそこに向かっている間は仕事モードに切り替える等、自分なりのスイッチを持つことが大事だと思う。
仕事を始める時と同じように終わる時も切り替えないと、いつまでも仕事のことが気になってリラックス出来なかったり、ズルズルと仕事をしてしまうことになりかねない。自分の場合はテレビをつけたり晩御飯を自炊したりして切り替えている。
以下はリモートワークとは直接関係ないけどフリーランスをやっているとよくある質問なのでまとめておく。
仕事はどうやって取ってくるの？ 会社員をしていると役割によっては仕事を取ってくるということにノータッチで、さらにWebエンジニアにとって営業的な活動は不慣れな人が多いからか、この事についてもよく聞かれる。営業って言っても知らない会社にいきなり電話したりとかしているわけではなく、知り合いだったり、知り合いからの紹介だったりが大半で、特に自分の場合はスケールさせたいと考えている方でもないのでその程度にしている。
近頃はフリーランス向けの案件紹介をしている会社もあるのでそういうのを利用することも出来るし、わりと蓋を開けてみればなんとかなるものだと思う。
ぶっちゃけ儲かるの？ 多分フリーランスのイメージとしてバリバリやっている感があるのか、稼いでいると思っている人は多いのではないかと思う。フリーランス＝儲かるというわけではないけど、たくさん稼ぎたいとした時に自分でどうしたら良いのか考えて行動することが出来るという点において、自由度が高いのではないかと思う。
会社員であれば歩合制でもなければ何かをしたらそれが即給料に反映されるということはないけど、フリーランスであればより条件の良い案件を受けたり、数を増やしたりあの手この手を講じることが出来る。
反対に儲けることに主眼を置かない働き方も検討することが出来る。一定期間がっつり働いたら長期休暇を取るとか、稼働時間を少なめにして自由な時間を増やすとかも出来なくはない。
最後に 2回に渡ってアレコレまとめてみた。働き方が多様化していく中での1つの選択肢としてフリーランスもこれからどんどん増えていくのだろうと思う一方で、まだまだ回りからは物珍しく見られることもあるので、またこれをネタに何か書いてみようと思う。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p><a href="http://eza-s.com/blog/2016/10/17/%e3%83%aa%e3%83%a2%e3%83%bc%e3%83%88%e3%83%af%e3%83%bc%e3%82%af%e3%82%92%e3%81%97%e3%81%a6%e3%81%a6%e3%82%88%e3%81%8f%e8%81%9e%e3%81%8b%e3%82%8c%e3%82%8b%e4%ba%8b/">リモートワークをしててよく聞かれる事</a>の続き。フリーランスのWebエンジニアとしてリモートワークをしててよく聞かれることについてのまとめ。</p>
<h2 id="オンオフの切り替え">オン／オフの切り替え</h2>
<p>作業場所として自宅を使う場合、自宅というのは元々生活するスペースなのでそこでどうやってオン／オフを切り替えているのか？というのもよく聞かれる。</p>
<p>理想的なのは仕事部屋として仕事以外のことはしない空間を用意することかもしれない。それは無理でも例えば作業机を用意してそこに向かっている間は仕事モードに切り替える等、自分なりのスイッチを持つことが大事だと思う。</p>
<p>仕事を始める時と同じように終わる時も切り替えないと、いつまでも仕事のことが気になってリラックス出来なかったり、ズルズルと仕事をしてしまうことになりかねない。自分の場合はテレビをつけたり晩御飯を自炊したりして切り替えている。</p>
<p>以下はリモートワークとは直接関係ないけどフリーランスをやっているとよくある質問なのでまとめておく。</p>
<h2 id="仕事はどうやって取ってくるの">仕事はどうやって取ってくるの？</h2>
<p>会社員をしていると役割によっては仕事を取ってくるということにノータッチで、さらにWebエンジニアにとって営業的な活動は不慣れな人が多いからか、この事についてもよく聞かれる。営業って言っても知らない会社にいきなり電話したりとかしているわけではなく、知り合いだったり、知り合いからの紹介だったりが大半で、特に自分の場合はスケールさせたいと考えている方でもないのでその程度にしている。</p>
<p>近頃はフリーランス向けの案件紹介をしている会社もあるのでそういうのを利用することも出来るし、わりと蓋を開けてみればなんとかなるものだと思う。</p>
<h2 id="ぶっちゃけ儲かるの">ぶっちゃけ儲かるの？</h2>
<p>多分フリーランスのイメージとしてバリバリやっている感があるのか、稼いでいると思っている人は多いのではないかと思う。フリーランス＝儲かるというわけではないけど、たくさん稼ぎたいとした時に自分でどうしたら良いのか考えて行動することが出来るという点において、自由度が高いのではないかと思う。</p>
<p>会社員であれば歩合制でもなければ何かをしたらそれが即給料に反映されるということはないけど、フリーランスであればより条件の良い案件を受けたり、数を増やしたりあの手この手を講じることが出来る。</p>
<p>反対に儲けることに主眼を置かない働き方も検討することが出来る。一定期間がっつり働いたら長期休暇を取るとか、稼働時間を少なめにして自由な時間を増やすとかも出来なくはない。</p>
<h2 id="最後に">最後に</h2>
<p>2回に渡ってアレコレまとめてみた。働き方が多様化していく中での1つの選択肢としてフリーランスもこれからどんどん増えていくのだろうと思う一方で、まだまだ回りからは物珍しく見られることもあるので、またこれをネタに何か書いてみようと思う。</p>
]]></content>
        </item>
        
        <item>
            <title>AngularJSでajaxの開始・終了時に処理を入れたい</title>
            <link>https://eza-s.com/blog/archives/32/</link>
            <pubDate>Sun, 30 Oct 2016 08:39:48 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/32/</guid>
            <description>AngularJSでajaxによる通信を行うにあたって以下のような共通の処理を入れたい事がある。
通信中にローディング画面を表示させたい 認証エラーの時にログイン画面に遷移させたい このような時は$httpProviderのinterceptorsプロパティを使う。
var app = angular.module(&amp;#39;myApp&amp;#39;, []); app.config([&amp;#39;$httpProvider&amp;#39;, function($httpProvider) { $httpProvider.interceptors.push([&amp;#39;$q&amp;#39;, function ($q) { return { request: function(config) { // do something on success return config; }, requestError: function(rejection) { // do something on error return $q.reject(rejection); }, response: function(response) { // do something on success return response; }, responseError: function(rejection) { // do something on error return $q.reject(rejection); } }; }]); }]); </description>
            <content type="html"><![CDATA[<p>AngularJSでajaxによる通信を行うにあたって以下のような共通の処理を入れたい事がある。</p>
<ul>
<li>通信中にローディング画面を表示させたい</li>
<li>認証エラーの時にログイン画面に遷移させたい</li>
</ul>
<p>このような時は$httpProviderのinterceptorsプロパティを使う。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">var</span> <span style="color:#a6e22e">app</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">angular</span>.<span style="color:#a6e22e">module</span>(<span style="color:#e6db74">&#39;myApp&#39;</span>, []);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">app</span>.<span style="color:#a6e22e">config</span>([<span style="color:#e6db74">&#39;$httpProvider&#39;</span>, <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">$httpProvider</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">$httpProvider</span>.<span style="color:#a6e22e">interceptors</span>.<span style="color:#a6e22e">push</span>([<span style="color:#e6db74">&#39;$q&#39;</span>, <span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">$q</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> {
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">request</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">config</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// do something on success
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">config</span>;
</span></span><span style="display:flex;"><span>      },
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">requestError</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">rejection</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// do something on error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">$q</span>.<span style="color:#a6e22e">reject</span>(<span style="color:#a6e22e">rejection</span>);
</span></span><span style="display:flex;"><span>      },
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">response</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">response</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// do something on success
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">response</span>;
</span></span><span style="display:flex;"><span>      },
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">responseError</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">rejection</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// do something on error
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">$q</span>.<span style="color:#a6e22e">reject</span>(<span style="color:#a6e22e">rejection</span>);
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    };
</span></span><span style="display:flex;"><span>  }]);
</span></span><span style="display:flex;"><span>}]);
</span></span></code></pre></div>]]></content>
        </item>
        
        <item>
            <title>リモートワークをしててよく聞かれる事</title>
            <link>https://eza-s.com/blog/archives/22/</link>
            <pubDate>Mon, 17 Oct 2016 02:15:48 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/22/</guid>
            <description>はじめに 自分はフリーランスのWebエンジニアとして8年近く仕事をしていて、大半は自宅で作業をしている。最近はリモートワークも広まりつつあるような気がするけれども、周りの人からどういう風にしているのか聞かれる事は多い。なのでリモートワークで気をつけている事など、どのように自宅で作業しているのか自分なりにまとめてみる。
リモート向きの仕事内容 周りの人と話してて一番多いのが「私は自宅で仕事するのはちょっと無理ですね」ていうパターン。それには後述するいくつかの要因があるけど、まずは1人で仕事するのに抵抗があるというのが大きいと思われる。
自分の場合はフリーランスになる前から1人でこなす仕事が多かったので作業場所が会社でも自宅でも大差ないので違和感無く出来たと思う。あと静かな環境の方が集中できるので、そういう意味で自宅は自分の中でもっとも静かな環境だ。
個人的な向き不向きやリモートで仕事したい／したくないはあると思うけど、それは抜きにして仕事内容が以下のいずれかに当てはまるのであればリモートでも可能だと言える。
やることに関してある程度任されている 役割分担や作業内容が明確になっている 反対に、
任されている部分が少なく独断で動きにくい 作業内容に不明な点が多く都度確認が必要 のような場合はリモートよりも集まって仕事した方がいいと思う。
サボったりしない？ これもよくある質問シリーズ。人に見られていない&amp;amp;自宅は家事や趣味など仕事以外に出来ることがあり、サボろうと思えばサボれる状況である。自分も実際のところ全くサボってないとは言えない。
だけどそれに対して監視するとか、稼働している事を証明するとかいうよりは、やらないといけない事に対して出来ているかどうかについての判断だったり、いつまでに何をやればいいのか合意が取れているかどうかの方が大事だと思う。それができていれば後の時間をどう使うかは自由なはずだ。
生活のリズム 朝◯時出社みたいな制約が無いと休日のように夜更かしして次の日も遅くに目が覚めたり、下手をすると昼夜逆転の生活に…なんてことも心配する人もいると思う。
自分の場合はそもそも夜型ではないので問題ないんだけど、それでも出来るだけ規則正しい生活をするよう心がけている。それはそういう当たり前の事を当たり前にするというのが心挫けそうな時（主に仕事が無くて）に支えになると思っているからだ。
最後に 他にもいくつかあるけど、今回はこのあたりで。
こうやって書いてみると、ここに書いてあるような心配事は会社勤めをしていれば無い訳で、改めて会社で働くというシステムはよく出来ているのだなぁと思うのであった。でもそこを乗り越えれば時間は比較的自由がきくし、色々自分で試行錯誤する楽しみのようなものもあるかと思う。例えるならトレーニングをするにあたって、ジムに行く事も出来るし自宅でも出来る。どちらが優れているとかではなくどちらも選べるようになっているというのが大事なのだと思う。</description>
            <content type="html"><![CDATA[<h2 id="はじめに">はじめに</h2>
<p>自分はフリーランスのWebエンジニアとして8年近く仕事をしていて、大半は自宅で作業をしている。最近はリモートワークも広まりつつあるような気がするけれども、周りの人からどういう風にしているのか聞かれる事は多い。なのでリモートワークで気をつけている事など、どのように自宅で作業しているのか自分なりにまとめてみる。</p>
<h2 id="リモート向きの仕事内容">リモート向きの仕事内容</h2>
<p>周りの人と話してて一番多いのが「私は自宅で仕事するのはちょっと無理ですね」ていうパターン。それには後述するいくつかの要因があるけど、まずは1人で仕事するのに抵抗があるというのが大きいと思われる。</p>
<p>自分の場合はフリーランスになる前から1人でこなす仕事が多かったので作業場所が会社でも自宅でも大差ないので違和感無く出来たと思う。あと静かな環境の方が集中できるので、そういう意味で自宅は自分の中でもっとも静かな環境だ。</p>
<p>個人的な向き不向きやリモートで仕事したい／したくないはあると思うけど、それは抜きにして仕事内容が以下のいずれかに当てはまるのであればリモートでも可能だと言える。</p>
<ul>
<li>やることに関してある程度任されている</li>
<li>役割分担や作業内容が明確になっている</li>
</ul>
<p>反対に、</p>
<ul>
<li>任されている部分が少なく独断で動きにくい</li>
<li>作業内容に不明な点が多く都度確認が必要</li>
</ul>
<p>のような場合はリモートよりも集まって仕事した方がいいと思う。</p>
<h2 id="サボったりしない">サボったりしない？</h2>
<p>これもよくある質問シリーズ。人に見られていない&amp;自宅は家事や趣味など仕事以外に出来ることがあり、サボろうと思えばサボれる状況である。自分も実際のところ全くサボってないとは言えない。</p>
<p>だけどそれに対して監視するとか、稼働している事を証明するとかいうよりは、やらないといけない事に対して出来ているかどうかについての判断だったり、いつまでに何をやればいいのか合意が取れているかどうかの方が大事だと思う。それができていれば後の時間をどう使うかは自由なはずだ。</p>
<h2 id="生活のリズム">生活のリズム</h2>
<p>朝◯時出社みたいな制約が無いと休日のように夜更かしして次の日も遅くに目が覚めたり、下手をすると昼夜逆転の生活に…なんてことも心配する人もいると思う。</p>
<p>自分の場合はそもそも夜型ではないので問題ないんだけど、それでも出来るだけ規則正しい生活をするよう心がけている。それはそういう当たり前の事を当たり前にするというのが心挫けそうな時（主に仕事が無くて）に支えになると思っているからだ。</p>
<h2 id="最後に">最後に</h2>
<p>他にもいくつかあるけど、今回はこのあたりで。</p>
<p>こうやって書いてみると、ここに書いてあるような心配事は会社勤めをしていれば無い訳で、改めて会社で働くというシステムはよく出来ているのだなぁと思うのであった。でもそこを乗り越えれば時間は比較的自由がきくし、色々自分で試行錯誤する楽しみのようなものもあるかと思う。例えるならトレーニングをするにあたって、ジムに行く事も出来るし自宅でも出来る。どちらが優れているとかではなくどちらも選べるようになっているというのが大事なのだと思う。</p>
]]></content>
        </item>
        
        <item>
            <title>AngularJSでページのタイトルを動的に変更したい</title>
            <link>https://eza-s.com/blog/archives/11/</link>
            <pubDate>Thu, 06 Oct 2016 09:39:49 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/11/</guid>
            <description>Webアプリケーションで、表示するページによってタイトルを動的に変更したいというのをAngularJSで実装した時のメモ。
使用したモジュール
https://github.com/nonplus/angular-ui-router-title
READMEに使い方書いてあるけど簡単に説明すると
bower install angular-ui-router-title でインストールするか、ダウンロードしたファイルを任意の場所に設置。
&amp;lt;script src=&amp;#34;bower_components/angular-ui-router-title/angular-ui-router-title.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt; をhtmlに追加。ダウンロードした場合はパスを適宜置き換える。
var app = angular.module(&amp;#39;myApp&amp;#39;, [&amp;#39;ng&amp;#39;, &amp;#39;ui.router.title&amp;#39;]); でui.router.titleモジュールを読み込む。
&amp;lt;html ng-app&amp;gt; &amp;lt;head&amp;gt; &amp;lt;title ng-bind=&amp;#34;($title || &amp;#39;Home&amp;#39;) + &amp;#39; - My Application&amp;#39;&amp;#34;&amp;gt;My Application&amp;lt;/title&amp;gt; &amp;lt;/head&amp;gt; ... タイトルの埋込例。$titleが設定されていればその内容が、無ければHomeが表示されて、その後に - My Application と続く。
$titleはUI Routerの$stateProvider.state(name, stateConfig)のstateConfigオブジェクトのresolveプロパティで設定する。
app.config([&amp;#39;$stateProvider&amp;#39;, function ($stateProvider) { $stateProvider .state(&amp;#39;home&amp;#39;, { ... resolve: { // 固定値 $title: function() { return &amp;#39;Home&amp;#39;; } } }) .state(&amp;#39;contacts&amp;#39;, { url: &amp;#39;/contacts&amp;#39;, ... resolve: { // コンタクトリスト contacts: [&amp;#39;Contacts&amp;#39;, function(Contacts) { // APIからリストを取得 return Contacts.</description>
            <content type="html"><![CDATA[<p>Webアプリケーションで、表示するページによってタイトルを動的に変更したいというのをAngularJSで実装した時のメモ。</p>
<p>使用したモジュール</p>
<p><a href="https://github.com/nonplus/angular-ui-router-title">https://github.com/nonplus/angular-ui-router-title</a></p>
<p>READMEに使い方書いてあるけど簡単に説明すると</p>
<pre tabindex="0"><code>bower install angular-ui-router-title
</code></pre><p>でインストールするか、ダウンロードしたファイルを任意の場所に設置。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#f92672">script</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;bower_components/angular-ui-router-title/angular-ui-router-title.js&#34;</span>&gt;&lt;/<span style="color:#f92672">script</span>&gt;
</span></span></code></pre></div><p>をhtmlに追加。ダウンロードした場合はパスを適宜置き換える。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#66d9ef">var</span> <span style="color:#a6e22e">app</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">angular</span>.<span style="color:#a6e22e">module</span>(<span style="color:#e6db74">&#39;myApp&#39;</span>, [<span style="color:#e6db74">&#39;ng&#39;</span>, <span style="color:#e6db74">&#39;ui.router.title&#39;</span>]);
</span></span></code></pre></div><p>でui.router.titleモジュールを読み込む。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>&lt;<span style="color:#f92672">html</span> <span style="color:#a6e22e">ng-app</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">head</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">title</span> <span style="color:#a6e22e">ng-bind</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;($title || &#39;Home&#39;) + &#39; - My Application&#39;&#34;</span>&gt;My Application&lt;/<span style="color:#f92672">title</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">head</span>&gt;
</span></span><span style="display:flex;"><span>...
</span></span></code></pre></div><p>タイトルの埋込例。$titleが設定されていればその内容が、無ければ<code>Home</code>が表示されて、その後に<code> - My Application</code> と続く。</p>
<p>$titleはUI Routerの$stateProvider.state(name, stateConfig)のstateConfigオブジェクトのresolveプロパティで設定する。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-js" data-lang="js"><span style="display:flex;"><span><span style="color:#a6e22e">app</span>.<span style="color:#a6e22e">config</span>([<span style="color:#e6db74">&#39;$stateProvider&#39;</span>, <span style="color:#66d9ef">function</span> (<span style="color:#a6e22e">$stateProvider</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">$stateProvider</span>
</span></span><span style="display:flex;"><span>    .<span style="color:#a6e22e">state</span>(<span style="color:#e6db74">&#39;home&#39;</span>, {
</span></span><span style="display:flex;"><span>      ...
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">resolve</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// 固定値
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#a6e22e">$title</span><span style="color:#f92672">:</span> <span style="color:#66d9ef">function</span>() { <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;Home&#39;</span>; }
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>    .<span style="color:#a6e22e">state</span>(<span style="color:#e6db74">&#39;contacts&#39;</span>, {
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">url</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;/contacts&#39;</span>,
</span></span><span style="display:flex;"><span>      ...
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">resolve</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// コンタクトリスト
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#a6e22e">contacts</span><span style="color:#f92672">:</span> [<span style="color:#e6db74">&#39;Contacts&#39;</span>, <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">Contacts</span>) {
</span></span><span style="display:flex;"><span>          <span style="color:#75715e">// APIからリストを取得
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>          <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">Contacts</span>.<span style="color:#a6e22e">query</span>();
</span></span><span style="display:flex;"><span>        }],
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// リストの件数を動的に設定
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#a6e22e">$title</span><span style="color:#f92672">:</span> [<span style="color:#e6db74">&#39;contacts&#39;</span>, <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">contacts</span>) {
</span></span><span style="display:flex;"><span>          <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;Contacts (&#39;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">contacts</span>.<span style="color:#a6e22e">length</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#39;)&#39;</span>;
</span></span><span style="display:flex;"><span>        }]
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>    .<span style="color:#a6e22e">state</span>(<span style="color:#e6db74">&#39;contact&#39;</span>, {
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">url</span><span style="color:#f92672">:</span> <span style="color:#e6db74">&#39;/contact/:contactId&#39;</span>,
</span></span><span style="display:flex;"><span>      ...
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">resolve</span><span style="color:#f92672">:</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// コンタクト1件取得
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#a6e22e">contact</span><span style="color:#f92672">:</span> [<span style="color:#e6db74">&#39;Contacts&#39;</span>, <span style="color:#e6db74">&#39;$stateParams&#39;</span>, <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">Contacts</span>, <span style="color:#a6e22e">$stateParams</span>) {
</span></span><span style="display:flex;"><span>          <span style="color:#75715e">// APIから1件取得
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>          <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">Contacts</span>.<span style="color:#a6e22e">get</span>({ <span style="color:#a6e22e">id</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">$stateParams</span>.<span style="color:#a6e22e">contactId</span> });
</span></span><span style="display:flex;"><span>        }],
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// contact.nameを動的に設定
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#a6e22e">$title</span><span style="color:#f92672">:</span> [<span style="color:#e6db74">&#39;contact&#39;</span>, <span style="color:#66d9ef">function</span>(<span style="color:#a6e22e">contact</span>) {
</span></span><span style="display:flex;"><span>          <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">contact</span>.<span style="color:#a6e22e">name</span>;
</span></span><span style="display:flex;"><span>        }]
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    })
</span></span><span style="display:flex;"><span>}]);
</span></span></code></pre></div><p>他にパンくずリストの機能もあるので必要に応じて使ってみるといいかも。</p>
]]></content>
        </item>
        
        <item>
            <title>Vagrantで仮想環境を構築した時にハマった事</title>
            <link>https://eza-s.com/blog/archives/4/</link>
            <pubDate>Tue, 04 Oct 2016 03:47:12 +0000</pubDate>
            
            <guid>https://eza-s.com/blog/archives/4/</guid>
            <description>VirtualBox + Vagrant + Ansible(ansible_local)で構築したrubyの開発環境を開発メンバー(windows環境)に使ってもらったところ、共有フォルダ内に作成したファイルがホストOS/ゲストOS間で参照出来ないという現象が発生した。vagrant-vbguestプラグインをインストールしても解消されず。vagrant起動時のログを見せてもらうと
C:\Path\to\project&amp;gt;vagrant up
Bringing machine &amp;#39;default&amp;#39; up with &amp;#39;virtualbox&amp;#39; provider...
==&amp;gt; default: Checking if box &amp;#39;ubuntu/trusty64&amp;#39; is up to date...
==&amp;gt; default: A newer version of the box &amp;#39;ubuntu/trusty64&amp;#39; is available! You currently
==&amp;gt; default: have version &amp;#39;20160816.0.0&amp;#39;. The latest is version &amp;#39;20160919.0.0&amp;#39;. Run
==&amp;gt; default: `vagrant box update` to update.
==&amp;gt; default: Clearing any previously set forwarded ports...
==&amp;gt; default: Clearing any previously set network interfaces.</description>
            <content type="html"><![CDATA[<p>VirtualBox + Vagrant + Ansible(ansible_local)で構築したrubyの開発環境を開発メンバー(windows環境)に使ってもらったところ、共有フォルダ内に作成したファイルがホストOS/ゲストOS間で参照出来ないという現象が発生した。vagrant-vbguestプラグインをインストールしても解消されず。vagrant起動時のログを見せてもらうと</p>
<pre tabindex="0"><code>C:\Path\to\project&gt;vagrant up
Bringing machine &#39;default&#39; up with &#39;virtualbox&#39; provider...
==&gt; default: Checking if box &#39;ubuntu/trusty64&#39; is up to date...
==&gt; default: A newer version of the box &#39;ubuntu/trusty64&#39; is available! You currently
==&gt; default: have version &#39;20160816.0.0&#39;. The latest is version &#39;20160919.0.0&#39;. Run
==&gt; default: `vagrant box update` to update.
==&gt; default: Clearing any previously set forwarded ports...
==&gt; default: Clearing any previously set network interfaces...
==&gt; default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==&gt; default: Forwarding ports...
    default: 3000 (guest) =&gt; 3000 (host) (adapter 1)
    default: 22 (guest) =&gt; 2222 (host) (adapter 1)
==&gt; default: Running &#39;pre-boot&#39; VM customizations...
==&gt; default: Booting VM...
==&gt; default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
==&gt; default: Machine booted and ready!
==&gt; default: Checking for guest additions in VM...
    default: The guest additions on this VM do not match the installed version of
    default: VirtualBox! In most cases this is fine, but in rare cases it can
    default: prevent things such as shared folders from working properly. If you see
    default: shared folder errors, please make sure the guest additions within the
    default: virtual machine match the version of VirtualBox you have installed on
    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 4.3.36
    default: VirtualBox Version: 5.1
==&gt; default: Configuring and enabling network interfaces...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

/sbin/ip -o -0 addr | grep -v LOOPBACK | awk &#39;{print $2}&#39; | sed &#39;s/://&#39;

Stdout from the command:



Stderr from the command:

/usr/bin/env: bash: No such file or directory
/etc/profile.d/rbenv.sh: line 2: $&#39;\r&#39;: command not found
stdin: is not a tty
bash: line 2: sed: command not found
bash: line 2: grep: command not found
</code></pre><p>こんな感じでPATH設定がおかしくなっていてGeustAdditionsを取得&amp;ビルドする所でコケている模様。ansibleでrbenvをインストールする際に</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>- <span style="color:#f92672">name</span>: <span style="color:#ae81ff">add rbenv path to bash_profile</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">copy</span>: <span style="color:#ae81ff">src=files/rbenv.sh dest=/etc/profile.d/rbenv.sh</span>
</span></span></code></pre></div><p>としてPATHを追加しているが該当ファイルの記述には問題なく、また別のwindows環境では再現しなかった。</p>
<pre tabindex="0"><code>/etc/profile.d/rbenv.sh: line 2: $&#39;\r&#39;: command not found
</code></pre><p>の \r ってのが気になって調べてみたら、windows環境のgitで改行コードの自動変換が設定されていてansibleコピー元のシェルスクリプトの改行コードがCRLFに変換されていたのが原因だった。</p>
<pre tabindex="0"><code>&gt; git config --global core.autoCRLF false
</code></pre><p>で改行コードの自動変換を無効に設定した後、開発環境のリポジトリをクローンし直して作業してもらって解決した。</p>
]]></content>
        </item>
        
    </channel>
</rss>
