読者です 読者をやめる 読者になる 読者になる

@半径とことこ60分

人間の認知範囲なんてそんなもんさと、鳥が囀った

プログラマーじゃないけどLaravel4入門(7)blogをつくる

Blade レンダリングエラー(だと思う)

不思議なことがありました。通常は linux 上で作業しているのですが、わけあって windows の XAMPP 上で続きの作業をすることになったのですが、記事の一覧を表示しようとすると、ブラウザが

@extends('backend.master')

としか表示しないのです。もちろん、app/views/backend/articles/index.blade.php の一行目です。dashboard はどうだろうとクリックしてみますと問題なくすべて表示されます。

laravel のバージョンはともに 4.2.8 、php は、linux が 5.5.8、XAMPPが 5.5.11、まあ問題ないでしょう。dump-autoload かと思い打ち込んでも変わらず、結局かなりかかりましたが、次のサイトをみつけ、

php - blade template not working probably in Laravel 4.1? - Stack Overflow

ドキュメントのテンプレートにあるように「コントローラーでレイアウトを宣言する」ことで解消されました。

その後、また linux に戻っているのですが、これまで通り

return View::make('backend.articles.index', compact('articles'));

で一覧が表示されています。何なんでしょう?

えっ!? ところが、昨日の今日です! 原因を探ってみようと、同じXAMPP上で、レイアウト宣言をはずして return に戻しても正常に表示されます。この間、何かしたんでしょうか? 記憶がありません。???

その後、正確な切り分けはできていないのですが、どうも文字コードに原因がありそうだというところまできています。

XAMPPの文字コード設定

解決しました。何のことはない、php文字コードUTF-8に設定すればOKでした。

xampp/php/php.ini

mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_output = pass

(2014/9/7) 

 

バックエンド/カテゴリ新規作成、編集、削除

これはもう簡単です。article でやったことの繰り返しです。

$ php artisan generate:scaffold category --fields="category:string" 

で、コードを自動生成し、CategoriesTableSeeder.php にいくつかデータが入るようコードを追加し、

$ php artisan db:seed --class=CategoriesTableSeeder

でダミーデータ作成。routes.php

Route::resource('categories', 'CategoriesController');

を追加し、それぞれ backend ディレクトリ以下にコントローラー CategoriesController.php と各ビューを書いていきます。

コードは、ausnichts/laravel4-blog · GitHub にあります。

で、こんな風にできあがりました。

f:id:ausnichts:20140821115637p:plain

f:id:ausnichts:20140821115641p:plain

f:id:ausnichts:20140821115645p:plain

記事とカテゴリのリレーション

さて、リレーション、うまくいくでしょうか?

DB:Eloquent ORM
hasOneとbelongsTo | WinRoadのLaravel4初心者講座
hasManyとbelongsTo | WinRoadのLaravel4初心者講座

これらのサイトを参考にやってみたら実に簡単! カテゴリと記事は、一(カテゴリ)対多(記事)の関係にありますから、

app/models/Category.php

public function articles()
{
  return $this->hasMany('Article');
}

と、書き加えます。ただ、現時点ではこのリレーションは使うことはなく、今は記事からそのカテゴリを呼び出す逆の関連づけが必要です。

app/models/Article.php

public function category()
{
  return $this->belongsTo('Category');
}

と定義します。 それぞれ規則通りであれば、第2,第3引数は省略できるそうです。

記事一覧にカテゴリ表示

で、定義した関連づけの呼び出しがこれまた便利にできています。

コントローラー ArticlesController.php は全く変更することなく、Article モデルを呼び出し必要なデータをビューに引き渡しているだけですが、app/views/backend/articles/index.blade.php

<td>{{ $article->category->category }}</td> 

と記述するだけで、記事のカテゴリーが表示されます。

ただ、今回の場合、これは例外的なケースなんですが、

Trying to get property of non-object (View: *********/laravel4-blog/app/views/backend/articles/index.blade.php)

のエラーに苦労させられました。何のことはない、記事の category_id カラムが空になっているためのエラーでした。

<td>{{ $article->category->category or '' }}</td>

と書き換えて、無事一覧表示でき、編集からカテゴリを選択しました。こうした設計感覚のないところがプログラマじゃない所以でしょうか。

記事新規作成、編集にカテゴリ選択

考え方としては、カテゴリの category と id をコントローラーで取得してビューに送り、セレクトボックスに展開すればいいことになります。

app/controllers/backend/ArticlesController.php

public function create()
{
  $categories = Category::all()->lists('category', 'id');
  return View::make('backend.articles.create', compact('categories'));
}

public function edit($id)
{
  try
  {
    $article = Article::findOrFail($id);
    $categories = Category::all()->lists('category', 'id');
    return View::make('backend.articles.edit', compact('article', 'categories'));
  }
  catch(ModelNotFoundException $e)
  {
    Notification::error('Not Found');
    return Redirect::action('ArticlesController@index');
  }
}

と変更します。

app/views/backend/articles/create.blade.php のカテゴリ部分は、

{{ Form::select('category_id', $categories, null, array('class' => 'form-control')) }} 

これで問題ないのですが、これですとついうっかり最初のカテゴリのまま保存してしまいますので、

{{ Form::select('category_id', array('default' => 'Please Select') + $categories, null, array('class' => 'form-control')) }}

とし、バリデーションルールの category_id に

'category_id' => 'exists:categories,id'

を指定し、必ず選択するように促しておきます。

同様に、app/views/backend/articles/edit.blade.php

{{ Form::select('category_id',array('default' => 'Please Select') + $categories, $article->category_id, array('class' => 'form-control')) }}

に変更します。

ということでカテゴリ、完成です!

f:id:ausnichts:20140821162116p:plain