Readouble

Laravel 5.0 Eloquent ORM

イントロダクションIntroduction

Eloquent ORMはLaravelに含まれている、美しくシンプルなアクティブレコードによるデーター操作の実装です。それぞれのデータベーステーブルは関連する「モデル」と結びついています。The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table.

使用を始める前に、cofig/database.phpの設定を確実に済ませて置いてください。Before getting started, be sure to configure a database connection in config/database.php.

基本的な使用法Basic Usage

使いはじめるには、まずEloquentモデルを作成しましょう。通常、モデルはappディレクトリー下に置きますが、composer.jsonファイルでオートロードするように指定した場所であれば、どこでも自由に設置できます。全てのEloquentモデルは、Illuminate\Database\Eloquent\Modelを拡張する必要があります。To get started, create an Eloquent model. Models typically live in the app directory, but you are free to place them anywhere that can be auto-loaded according to your composer.json file. All Eloquent models extend Illuminate\Database\Eloquent\Model.

Eloquentモデルの定義Defining An Eloquent Model

class User extends Model {}

また、make:modelコマンドを使用し、Eloquentモデルを生成することもできます。You may also generate Eloquent models using the make:model command:

php artisan make:model User

Userモデルにどのテーブルを使用するか、Eloquentに指定していない点に注目してください。クラス名を複数形のスネークケースにしたものがテーブル名として使用されます。今回の例でEloquentは、Userモデルをusersテーブルに保存します。他の名前を使用したい場合は明示的に指定します。モデルのtableプロパティを定義し、テーブル名を指定します。Note that we did not tell Eloquent which table to use for our User model. The "snake case", plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the User model stores records in the users table. You may specify a custom table by defining a table property on your model:

class User extends Model {

	protected $table = 'my_users';

}

注目: Eloquentは更にテーブルの主キーが、idというカラム名であると想定しています。この規約をオーバーライドする場合はprimaryKeyプロパティを定義してください。同様に、connectionプロパティを定義することで、そのモデルを取り扱うデータベース接続をオーバーライドすることもできます。Note: Eloquent will also assume that each table has a primary key column named id. You may define a primaryKey property to override this convention. Likewise, you may define a connection property to override the name of the database connection that should be used when utilizing the model.

一度モデルを定義したら、テーブルのレコードを取得したり、作成したりする準備は整いました。デフォルトではupdated_at(更新時間)とcreated_at(作成時間)カラムをテーブルに用意しておく必要があることに注意してください。これらのカラムを自動的に更新したくないなら、$timestampsfalseに設定してください。Once a model is defined, you are ready to start retrieving and creating records in your table. Note that you will need to place updated_at and created_at columns on your table by default. If you do not wish to have these columns automatically maintained, set the $timestamps property on your model to false.

全レコードの取得Retrieving All Records

$users = User::all();

主キーから1レコードを取得Retrieving A Record By Primary Key

$user = User::find(1);

var_dump($user->name);

クエリービルダーの全メソッドは、Eloquentモデルを使ってクエリーする場合に使用できます。Note: All methods available on the query builder[/docs/queries] are also available when querying Eloquent models.

主キーでモデルを取得、もしくは例外を投げるRetrieving A Model By Primary Key Or Throw An Exception

モデルが見つからない場合、例外を投げたいこともあることでしょう。firstOrFailメソッドを使用してください。Sometimes you may wish to throw an exception if a model is not found. To do this, you may use the firstOrFail method:

$model = User::findOrFail(1);

$model = User::where('votes', '>', 100)->firstOrFail();

例外を捉え、必要に応じログを取るなり、エラーページを表示するなりできます。ModelNotFoundException例外を補足するには、ファイルにロジックを追加します。Doing this will let you catch the exception so you can log and display an error page as necessary. To catch the ModelNotFoundException, add some logic to your app/Exceptions/Handler.php file.

use Illuminate\Database\Eloquent\ModelNotFoundException;

class Handler extends ExceptionHandler {

	public function render($request, Exception $e)
	{
		if ($e instanceof ModelNotFoundException)
		{
			// モデルが見つからない場合のカスタムロジック
		}

		return parent::render($request, $e);
	}

}

Eloquentモデルを使用したクエリーQuerying Using Eloquent Models

$users = User::where('votes', '>', 100)->take(10)->get();

foreach ($users as $user)
{
	var_dump($user->name);
}

Eloquentを使った集計Eloquent Aggregates

もちろんクエリービルダーの集計関数も使用できます。Of course, you may also use the query builder aggregate functions.

$count = User::where('votes', '>', 100)->count();

Fluentインターフェイスで必要なクエリーを生成できない場合、whereRawを使用してください。If you are unable to generate the query you need via the fluent interface, feel free to use whereRaw:

$users = User::whereRaw('age > ? and votes = 100', [25])->get();

結果の分割Chunking Results

大きな(数千の)Eloquentレコードを処理する必要がある場合、RAMが食いつぶされないように、chunkコマンドを利用してください。If you need to process a lot (thousands) of Eloquent records, using the chunk command will allow you to do without eating all of your RAM:

User::chunk(200, function($users)
{
	foreach ($users as $user)
	{
		//
	}
});

最初の引数には「チャンク(塊)」ごとにいくつのレコードを処理するかを渡します。2番めの引数にはクロージャーを渡し、そのデータベースからの結果をチャンクごとに処理するコードを記述します。The first argument passed to the method is the number of records you wish to receive per "chunk". The Closure passed as the second argument will be called for each chunk that is pulled from the database.

クエリー接続の指定Specifying The Query Connection

Eloquentクエリーの実行時に、データベース接続を指定することができます。onメソッドを使用してください。You may also specify which database connection should be used when running an Eloquent query. Simply use the on method:

$user = User::on('connection-name')->find(1);

Read/Write接続を利用している場合に、"write"接続で強制的にクエリーする場合は、以下のメソッドを使用してください。If you are using read / write connections[/docs/{{version}}/database#read-write-connections], you may force the query to use the "write" connection with the following method:

$user = User::onWriteConnection()->find(1);

複数代入Mass Assignment

新しいモデルを作成する時、モデルのコンストラクターに属性の配列を渡せます。渡した属性は、複数代入としてモデルに結び付けられます。これは便利ですが、ユーザーの入力を闇雲にモデルに渡してしまうことは、重大なセキュリティーの欠陥になり得ます。何でもかんでもユーザー入力をモデルに渡せば、ユーザーは何でもかんでもモデルの属性を変更できるのです。このため、全てのEloquentモデルは複数代入されないよう、デフォルトとして保護されています。When creating a new model, you pass an array of attributes to the model constructor. These attributes are then assigned to the model via mass-assignment. This is convenient; however, can be a serious security concern when blindly passing user input into a model. If user input is blindly passed into a model, the user is free to modify any and all of the model's attributes. For this reason, all Eloquent models protect against mass-assignment by default.

複数代入を使用するにはfillableguardedプロパティをモデルに設定してください。To get started, set the fillable or guarded properties on your model.

モデルの複数代入可能な属性の指定Defining Fillable Attributes On A Model

fillableプロパティーは複数代入を許す属性を指定します。クラスとインスタンスの両レベルで設定できます。The fillable property specifies which attributes should be mass-assignable. This can be set at the class or instance level.

class User extends Model {

	protected $fillable = ['first_name', 'last_name', 'email'];

}

この例では、リストされている3属性のみ、複数代入されます。In this example, only the three listed attributes will be mass-assignable.

保護するモデル属性の指定Defining Guarded Attributes On A Model

このfillableの反対がguardedです。「ホワイトリスト」ではなく、「ブラックリスト」として利用します。The inverse of fillable is guarded, and serves as a "black-list" instead of a "white-list":

class User extends Model {

	protected $guarded = ['id', 'password'];

}

注目:guardedを使用する場合、守られて(guarded)いないカラムが更新されてしまうため、Input::get()や、ユーザーがコントロールできる配列をそのまま、saveupdateメソッドには渡すべきではありません。Note: When using guarded, you should still never pass Input::get() or any raw array of user controlled input into a save or update method, as any column that is not guarded may be updated.

全属性を複数代入から保護Blocking All Attributes From Mass Assignment

前の例では、idpassword属性が複数代入の対象外となります。その他の属性は複数代入されます。属性を複数代入から保護するには、guardプロパティーを使用してください。In the example above, the id and password attributes may not be mass assigned. All other attributes will be mass assignable. You may also block all attributes from mass assignment using the guard property:

protected $guarded = ['*'];

INSERT、UPDATE、DELETEInsert, Update, Delete

モデルから新しいレコードを作成するには、モデルの新しいインスタンスを作成し、saveメソッドを呼び出します。To create a new record in the database from a model, simply create a new model instance and call the save method.

新しいモデルの保存Saving A New Model

$user = new User;

$user->name = 'John';

$user->save();

注目: Eloquentモデルは、新規作成時にキーを自動的に増加させるのが、典型的な使用法です。しかし、自分でキーを設定したい場合は、モデルのincrementingプロパティをfalseにセットしてください。Note: Typically, your Eloquent models will have auto-incrementing keys. However, if you wish to specify your own keys, set the incrementing property on your model to false.

もしくは、一行書くだけで新しいモデルを保存するために、createメソッドを使用することも可能です。挿入されたモデルのインスタンスが、メソッドから返されます。このメソッドを使用する場合も、全Eloquentモデルが複数代入からデフォルトで保護されているため、使用する前に操作対象のモデルに対し、fillableguardedプロパティのどちらかで代入可能にする属性を指定しておく必要があります。You may also use the create method to save a new model in a single line. The inserted model instance will be returned to you from the method. However, before doing so, you will need to specify either a fillable or guarded attribute on the model, as all Eloquent models protect against mass-assignment.

IDの自動増分を設定しているモデルを保存、もしくは新しく作成した後、そのIDを取得したい場合は、オブジェクトのid属性にアクセスしてください。After saving or creating a new model that uses auto-incrementing IDs, you may retrieve the ID by accessing the object's id attribute:

$insertedId = $user->id;

保護されたモデル属性の設定Setting The Guarded Attributes On The Model

class User extends Model {

	protected $guarded = ['id', 'account_id'];

}

createメソッドの使用Using The Model Create Method

// データベースに新しいユーザーを作成する
$user = User::create(['name' => 'John']);

// 属性により、ユーザーを取得するか、存在していない場合は作成する
$user = User::firstOrCreate(['name' => 'John']);

// 属性により、ユーザーを取得するか、新しいインスタンスを生成する
$user = User::firstOrNew(['name' => 'John']);

取得したモデルの更新Updating A Retrieved Model

モデルを更新する場合は、先ず取得し、その内容を変更してから、saveメソッドを使用します。To update a model, you may retrieve it, change an attribute, and use the save method:

$user = User::find(1);

$user->email = 'john@foo.com';

$user->save();

モデルと関連の保存Saving A Model And Relationships

そのモデルだけでなく、関連を全部まとめて保存したい場合もあるでしょう。そんな場合は、pushメソッドを使用してください。Sometimes you may wish to save not only a model, but also all of its relationships. To do so, you may use the push method:

$user->push();

複数のモデルに対しクエリーで更新することもできます。You may also run updates as queries against a set of models:

$affectedRows = User::where('votes', '>', 100)->update(['status' => 2]);

注意: 上記のように一連のモデルをまとめてEloquentクエリービルダーで更新する場合、モデルのイベントは発行されません。Note: No model events are fired when updating a set of models via the Eloquent query builder.

既存モデルの削除Deleting An Existing Model

削除するには、インスタンスに対しdeleteメソッドを使用するだけです。To delete a model, simply call the delete method on the instance:

$user = User::find(1);

$user->delete();

キー指定による既存モデルの削除Deleting An Existing Model By Key

User::destroy(1);

User::destroy([1, 2, 3]);

User::destroy(1, 2, 3);

もちろん、deleteクエリーで複数のモデルを削除できます。Of course, you may also run a delete query on a set of models:

$affectedRows = User::where('votes', '>', 100)->delete();

モデルのタイムスタンプだけのアップデートUpdating Only The Model's Timestamps

モデルのタイムスタンプだけをアップデートしたい場合は、touchメソッドを使用します。If you wish to simply update the timestamps on a model, you may use the touch method:

$user->touch();

ソフトデリートSoft Deleting

モデルをソフトデリートする場合、データーベースから実際に削除されるわけではありません。代わりにレコードへdeleted_atタイムスタンプをセットします。モデルのソフトデリートを有効にするには、SoftDeletesトレイトを適用してください。When soft deleting a model, it is not actually removed from your database. Instead, a deleted_at timestamp is set on the record. To enable soft deletes for a model, apply the SoftDeletes to the model:

use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model {

	use SoftDeletes;

	protected $dates = ['deleted_at'];

}

deleted_atカラムをテーブルに追加するには、マイグレーションでsoftDeletesメソッドが使用できます。To add a deleted_at column to your table, you may use the softDeletes method from a migration:

$table->softDeletes();

これでモデルに対し、deleteメソッドを使用すれば、deleted_atカラムに現在の時間がセットされます。ソフトデリートされたモデルに対しクエリーがあっても、「削除済み」のモデルはクエリー結果に含まれません。Now, when you call the delete method on the model, the deleted_at column will be set to the current timestamp. When querying a model that uses soft deletes, the "deleted" models will not be included in query results.

ソフトデリートされたモデルも結果に含めるように強制Forcing Soft Deleted Models Into Results

ソフトデリートされたモデルも結果に含めたい場合、withTrashedメソッドをクエリーに使用してください。To force soft deleted models to appear in a result set, use the withTrashed method on the query:

$users = User::withTrashed()->where('account_id', 1)->get();

定義済みの関連付けに対して、withTrashedメソッドを使用することができます。The withTrashed method may be used on a defined relationship:

$user->posts()->withTrashed()->get();

ソフトデリートされたモデルのみに対しクエリーしたい場合は、onlyTrashedメソッドを使用します。If you wish to only receive soft deleted models in your results, you may use the onlyTrashed method:

$users = User::onlyTrashed()->where('account_id', 1)->get();

ソフトデリートされたモデルを既存状態へ復活させるには、restoreメソッドを使ってください。To restore a soft deleted model into an active state, use the restore method:

$user->restore();

restoreメソッドはクエリーと共に使用することもできます。You may also use the restore method on a query:

User::withTrashed()->where('account_id', 1)->restore();

withTrashedと同様に、restoreメソッドも、関連付けに対して使用することができます。Like with withTrashed, the restore method may also be used on relationships:

$user->posts()->restore();

モデルを本当にデータベースから削除したい場合は、forceDeleteメソッドを使用してください。If you wish to truly remove a model from the database, you may use the forceDelete method:

$user->forceDelete();

これも関連付けに対して使用することもできます。The forceDelete method also works on relationships:

$user->posts()->forceDelete();

指定したモデルのインスタンスがソフトデリートされたものか判断するには、trashedメソッドを使用します。To determine if a given model instance has been soft deleted, you may use the trashed method:

if ($user->trashed())
{
	//
}

タイムスタンプTimestamps

デフォルトでEloquentはデータベースのcreated_at(作成時間)とupdated_at(更新時間)カラムを自動的に更新します。上記のタイムスタンプカラムをテーブルに追加するだけで、Eloquentが残りの面倒を見ます。Eloquentによる2カラムのメンテナンスがご希望でなければ、モデルに以下のプロパティを追加してください。By default, Eloquent will maintain the created_at and updated_at columns on your database table automatically. Simply add these timestamp columns to your table and Eloquent will take care of the rest. If you do not wish for Eloquent to maintain these columns, add the following property to your model:

自動タイムスタンプ無効Disabling Auto Timestamps

class User extends Model {

	protected $table = 'users';

	public $timestamps = false;

}

タイムスタンプのカスタム形式の指定Providing A Custom Timestamp Format

タイムスタンプのフォーマットをカスタマイズしたい場合は、getDateFormatメソッドをモデルの中でオーバーライドしてください。If you wish to customize the format of your timestamps, you may override the getDateFormat method in your model:

class User extends Model {

	protected function getDateFormat()
	{
		return 'U';
	}

}

クエリースコープQuery Scopes

クエリースコープの定義Defining A Query Scope

スコープにより、モデルに対するクエリーロジックを簡単に再使用できるようにできます。スコープを定義するには、モデルのメソッド名の先頭にscopeを付けてください。Scopes allow you to easily re-use query logic in your models. To define a scope, simply prefix a model method with scope:

class User extends Model {

	public function scopePopular($query)
	{
		return $query->where('votes', '>', 100);
	}

	public function scopeWomen($query)
	{
		return $query->whereGender('W');
	}

}

クエリースコープの使用Utilizing A Query Scope

$users = User::popular()->women()->orderBy('created_at')->get();

動的スコープDynamic Scopes

スコープに引数を渡したい場合もあるでしょう。スコープのメソッドに引数を追加するだけです。Sometimes you may wish to define a scope that accepts parameters. Just add your parameters to your scope function:

class User extends Model {

	public function scopeOfType($query, $type)
	{
		return $query->whereType($type);
	}

}

後はスコープの呼び出し時に、引数を指定してください。Then pass the parameter into the scope call:

$users = User::ofType('member')->get();

グローバルスコープGlobal Scopes

モデルで動かす全クエリーに対し、適用する必要があるスコープを定義することもあるでしょう。実際に、Eloquentの「ソフトデリート」機能はこれを使用しています。グローバルスコープは、PHPのトレイトとIlluminate\Database\Eloquent\ScopeInterfaceの実装を組み合わせ、定義します。Sometimes you may wish to define a scope that applies to all queries performed on a model. In essence, this is how Eloquent's own "soft delete" feature works. Global scopes are defined using a combination of PHP traits and an implementation of Illuminate\Database\Eloquent\ScopeInterface.

最初にトレイトを定義します。例として、Laravelに組み込まれているSoftDeletesを使いましょう。First, let's define a trait. For this example, we'll use the SoftDeletes that ships with Laravel:

trait SoftDeletes {

	/**
	 * モデルのため、ソフトデリートトレイトを起動する
	 *
	 * @return void
	 */
	public static function bootSoftDeletes()
	{
		static::addGlobalScope(new SoftDeletingScope);
	}

}

Eloquentモデルにbootトレイトの名前という命名規則に一致するメソッドが存在するならば、グローバールスコープを登録したり、もしくは皆さんが行いたい別の操作をしたりする機会を作るため、Eloquentモデルの起動時に対象のトレイトメソッドが呼び出されます。スコープはapplyremoveメソッドの2つを持つ、ScopeInterfaceを実装しなくてはなりません。If an Eloquent model uses a trait that has a method matching the bootNameOfTrait naming convention, that trait method will be called when the Eloquent model is booted, giving you an opportunity to register a global scope, or do anything else you want. A scope must implement ScopeInterface, which specifies two methods: apply and remove.

applyメソッドはIlluminate\Database\Eloquent\Builderクエリービルダーオブジェクトを引数に取り、Modelは適用先です。applyメソッドは、そのスコープで追加したいwhere節を付け加えることに責任を持ちます。removeメソッドもBuilderオブジェクトとModelを引数として受け取り、applyで行う操作を逆転することに責任を持ちます。言い換えれば、removeは追加したwhere(もしくは他の節も全部)を削除する必要があります。これらを当てはめると、SoftDeletingScopeは次のようになります。The apply method receives an Illuminate\Database\Eloquent\Builder query builder object and the Model it's applied to, and is responsible for adding any additional where clauses that the scope wishes to add. The remove method also receives a Builder object and Model and is responsible for reversing the action taken by apply. In other words, remove should remove the where clause (or any other clause) that was added. So, for our SoftDeletingScope, the methods look something like this:

/**
 * 指定されたEloquentクエリービルダーにスコープを適用する
 *
 * @param  \Illuminate\Database\Eloquent\Builder  $builder
 * @param  \Illuminate\Database\Eloquent\Model  $model
 * @return void
 */
public function apply(Builder $builder, Model $model)
{
	$builder->whereNull($model->getQualifiedDeletedAtColumn());

	$this->extend($builder);
}

/**
 * 指定されたEloquentクエリービルダーからスコープを削除する
 *
 * @param  \Illuminate\Database\Eloquent\Builder  $builder
 * @param  \Illuminate\Database\Eloquent\Model  $model
 * @return void
 */
public function remove(Builder $builder, Model $model)
{
	$column = $model->getQualifiedDeletedAtColumn();

	$query = $builder->getQuery();

	foreach ((array) $query->wheres as $key => $where)
	{
		// where節がソフトデリートのデータ制約によるものであれば、クエリーから削除し
        // whereのキーをリセットする。これにより開発者は削除済みモデルを関連付けに
		// 含めることができ、遅延ロードされた結果をセットできる。
		if ($this->isSoftDeleteConstraint($where, $column))
		{
			unset($query->wheres[$key]);

			$query->wheres = array_values($query->wheres);
		}
	}
}

リレーションRelationships

もちろん、皆さんのデータベーステーブルは他のテーブルと関連していることでしょう。例えば、ブログポストは多くのコメントを持つでしょうし、注文は購入したユーザーと関連しているでしょう。Eloquentはこれらの関連を簡単に操作できるように管理します。Laravelは多くの関連をサポートしています。Of course, your database tables are probably related to one another. For example, a blog post may have many comments, or an order could be related to the user who placed it. Eloquent makes managing and working with these relationships easy. Laravel supports many types of relationships:

1対1One To One

1対1関係の定義Defining A One To One Relation

1対1関係は基本です。例えば、UserモデルはPhoneモデルを一つ持つ("has one")としましょう。この関係をEloquentで定義します。A one-to-one relationship is a very basic relation. For example, a User model might have one Phone. We can define this relation in Eloquent:

class User extends Model {

	public function phone()
	{
		return $this->hasOne('App\Phone');
	}

}

hasOneメソッドの最初の引数は関係するモデルの名前です。関連を定義したら、Eloquentの動的プロパティを使用し取得できます。The first argument passed to the hasOne method is the name of the related model. Once the relationship is defined, we may retrieve it using Eloquent's dynamic properties[#dynamic-properties]:

$phone = User::find(1)->phone;

この文は以下のSQLとして動作します。The SQL performed by this statement will be as follows:

select * from users where id = 1

select * from phones where user_id = 1

Eloquentはモデル名を元に、関連の外部キーを決めることに注目してください。この例の場合、Phoneモデルはuser_id外部キーを使用しようとします。この規約をオーバーライドしたいときは、hasOneメソッドの第2引数を指定してください。さらに関連で使用するローカルカラムを指定するために、メソッドの第3引数を渡すこともできます。Take note that Eloquent assumes the foreign key of the relationship based on the model name. In this case, Phone model is assumed to use a user_id foreign key. If you wish to override this convention, you may pass a second argument to the hasOne method. Furthermore, you may pass a third argument to the method to specify which local column that should be used for the association:

return $this->hasOne('App\Phone', 'foreign_key');

return $this->hasOne('App\Phone', 'foreign_key', 'local_key');

逆の関連付の定義Defining The Inverse Of A Relation

Phoneモデルの関連を逆に定義するには、belongsToメソッドを使います。To define the inverse of the relationship on the Phone model, we use the belongsTo method:

class Phone extends Model {

	public function user()
	{
		return $this->belongsTo('App\User');
	}

}

上の例で、Eloquentはphonesテーブルのuser_idカラムを探します。もし、他の外部キーを定義したい場合は、belongsToメソッドの第2引数に渡してください。In the example above, Eloquent will look for a user_id column on the phones table. If you would like to define a different foreign key column, you may pass it as the second argument to the belongsTo method:

class Phone extends Model {

	public function user()
	{
		return $this->belongsTo('App\User', 'local_key');
	}

}

さらに、親テーブルの関連するカラム名を第3引数として指定するできます。Additionally, you pass a third parameter which specifies the name of the associated column on the parent table:

class Phone extends Model {

	public function user()
	{
		return $this->belongsTo('App\User', 'local_key', 'parent_key');
	}

}

1対多One To Many

1対多の関連の例として、「プログポストは多くのコメントを持つ(has many)」があります。このような関係をモデルに定義します。An example of a one-to-many relation is a blog post that "has many" comments. We can model this relation like so:

class Post extends Model {

	public function comments()
	{
		return $this->hasMany('App\Comment');
	}

}

これで動的プロパティを使用し、ポストのコメントへアクセスできます。Now we can access the post's comments through the dynamic property[#dynamic-properties]:

$comments = Post::find(1)->comments;

取得するコメントを制限する必要がある場合、commentsメソッドを呼び出し条件をチェーンでつなげることができます。If you need to add further constraints to which comments are retrieved, you may call the comments method and continue chaining conditions:

$comments = Post::find(1)->comments()->where('title', '=', 'foo')->first();

ここでも、hasManyメソッドの第2引数を指定し、外部キーの規約をオーバーライドできます。さらに、hasOneリレーションと同様、ローカルカラムも指定できます。Again, you may override the conventional foreign key by passing a second argument to the hasMany method. And, like the hasOne relation, the local column may also be specified:

return $this->hasMany('App\Comment', 'foreign_key');

return $this->hasMany('App\Comment', 'foreign_key', 'local_key');

逆の関連付の定義Defining The Inverse Of A Relation

Commentモデルに逆の関係を定義するには、belongsToを使用します。To define the inverse of the relationship on the Comment model, we use the belongsTo method:

class Comment extends Model {

	public function post()
	{
		return $this->belongsTo('App\Post');
	}

}

多対多Many To Many

多対多の関係はもっと複雑なリレーションタイプです。このような関係として、ユーザ(user)が多くの役目(roles)を持ち、役目(role)も大勢のユーザー(users)に共有されるという例が挙げられます。例えば、多くのユーザーは"管理者"の役目を持っているとしましょう。usersrolesrole_userの3テーブルがこの関係には必要です。role_userテーブルは関係するモデル名をアルファベット順に並べたもので、user_idrole_idを持つ必要があります。Many-to-many relations are a more complicated relationship type. An example of such a relationship is a user with many roles, where the roles are also shared by other users. For example, many users may have the role of "Admin". Three database tables are needed for this relationship: users, roles, and role_user. The role_user table is derived from the alphabetical order of the related model names, and should have user_id and role_id columns.

多対多の関係はbelongsToManyメソッドで定義します。We can define a many-to-many relation using the belongsToMany method:

class User extends Model {

	public function roles()
	{
		return $this->belongsToMany('App\Role');
	}

}

では、Userモデルを通して、役割を取得しましょう。Now, we can retrieve the roles through the User model:

$roles = User::find(1)->roles;

もしピボットテーブル名に規約から外れた名前を使用したい場合は、belongsToManyメソッドの第2引数に渡してください。If you would like to use an unconventional table name for your pivot table, you may pass it as the second argument to the belongsToMany method:

return $this->belongsToMany('App\Role', 'user_roles');

更に関係するキー名の規約をオーバーライドするには:You may also override the conventional associated keys:

return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'foo_id');

もちろん、Roleモデルに対し逆のリレーションを定義することもできます。Of course, you may also define the inverse of the relationship on the Role model:

class Role extends Model {

	public function users()
	{
		return $this->belongsToMany('App\User');
	}

}

他テーブルを経由した多対多Has Many Through

「〜経由の多対多(has many through)」リレーションは、仲介するテーブルを通して、直接関連付けしていないテーブルへアクセスするための、便利な近道を提供します。例えば、CountryモデルはUsersモデルを経由して、多くのPostsを所有することでしょう。テーブルは以下のような構成になります。The "has many through" relation provides a convenient short-cut for accessing distant relations via an intermediate relation. For example, a Country model might have many Post through a User model. The tables for this relationship would look like this:

countries
	id - integer
	name - string

users
	id - integer
	country_id - integer
	name - string

posts
	id - integer
	user_id - integer
	title - string

例えpostsテーブルにcountry_idが存在しなくても、hasManyThroughリレーションでは、CountryのPostへ、$country->postsによりアクセスできます。関連を定義付けましょう。Even though the posts table does not contain a country_id column, the hasManyThrough relation will allow us to access a country's posts via $country->posts. Let's define the relationship:

class Country extends Model {

	public function posts()
	{
		return $this->hasManyThrough('App\Post', 'App\User');
	}

}

関連付けのキーを手動で指定したい場合、メソッドの第3引数と、第4引数として渡して下さい。If you would like to manually specify the keys of the relationship, you may pass them as the third and fourth arguments to the method:

class Country extends Model {

	public function posts()
	{
		return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id');
	}

}

多様対応関係Polymorphic Relations

多様対応(polymorphic:ポリモーフィック)関係は、あるモデルを一つの関係だけで、複数のモデルに所属させるものです。例えば写真モデルがあり、スタッフモデルと注文モデルの両方に所属しているとしましょう。この関係を次のように定義できます。Polymorphic relations allow a model to belong to more than one other model, on a single association. For example, you might have a photo model that belongs to either a staff model or an order model. We would define this relation like so:

class Photo extends Model {

	public function imageable()
	{
		return $this->morphTo();
	}

}

class Staff extends Model {

	public function photos()
	{
		return $this->morphMany('App\Photo', 'imageable');
	}

}

class Order extends Model {

	public function photos()
	{
		return $this->morphMany('App\Photo', 'imageable');
	}

}

多様対応関係で取得するRetrieving A Polymorphic Relation

では、スタッフと注文を通して、写真を取得してみましょう。Now, we can retrieve the photos for either a staff member or an order:

$staff = Staff::find(1);

foreach ($staff->photos as $photo)
{
	//
}

多様対応関連の所有者を取得するRetrieving The Owner Of A Polymorphic Relation

しかし、本当の「多様対応関係」マジックは、スタッフと注文を写真('Photo')モデルを通じてアクセスする場合に現れます。However, the true "polymorphic" magic is when you access the staff or order from the Photo model:

$photo = Photo::find(1);

$imageable = $photo->imageable;

Photoモデルのimageable関係は写真を所有しているモデルのタイプにより、StaffもしくはOrderどちらかのインスタンスをリターンします。The imageable relation on the Photo model will return either a Staff or Order instance, depending on which type of model owns the photo.

多様対応関係のテーブル構造Polymorphic Relation Table Structure

これがどの様に動作するのか理解を助けるために、多様対応関係のデータベース構造を説明しましょう。To help understand how this works, let's explore the database structure for a polymorphic relation:

staff
	id - integer
	name - string

orders
	id - integer
	price - integer

photos
	id - integer
	path - string
	imageable_id - integer
	imageable_type - string

注目すべき鍵となるフィールドは、photosテーブルのimageable_idimageable_typeです。この例の場合、IDは所有しているスタッフか注文のIDで、タイプは所有しているモデルのクラス名です。これにより、ORMが所有しているモデルのタイプを決定し、imageable関係でアクセスした時にそのモデルをリターンする仕組みです。The key fields to notice here are the imageable_id and imageable_type on the photos table. The ID will contain the ID value of, in this example, the owning staff or order, while the type will contain the class name of the owning model. This is what allows the ORM to determine which type of owning model to return when accessing the imageable relation.

多対多−多様対応関係Many To Many Polymorphic Relations

多対多−多様対応関係のテーブル構造Polymorphic Many To Many Relation Table Structure

伝統的な多様対応関係に加え、多対多-多様対応関係も指定することができます。例えば、ブログのPostVideoモデルは、Tagモデルに対する多様対応関係を共有できます。最初に、テーブル構造を確認しましょう。In addition to traditional polymorphic relations, you may also specify many-to-many polymorphic relations. For example, a blog Post and Video model could share a polymorphic relation to a Tag model. First, let's examine the table structure:

posts
	id - integer
	name - string

videos
	id - integer
	name - string

tags
	id - integer
	name - string

taggables
	tag_id - integer
	taggable_id - integer
	taggable_type - string

次に、モデルにその関係を用意しましょう。PostVideoモデルは、tagsメソッドを通じ、両方共にmorphToMany関係を持ちます。Next, we're ready to setup the relationships on the model. The Post and Video model will both have a morphToMany relationship via a tags method:

class Post extends Model {

	public function tags()
	{
		return $this->morphToMany('App\Tag', 'taggable');
	}

}

Tagモデルでは、それぞれの関係を表すメソッドを定義します。The Tag model may define a method for each of its relationships:

class Tag extends Model {

	public function posts()
	{
		return $this->morphedByMany('App\Post', 'taggable');
	}

	public function videos()
	{
		return $this->morphedByMany('App\Video', 'taggable');
	}

}

リレーションの問い合わせQuerying Relations

SELECT時にリレーションを問い合わせるQuerying Relations When Selecting

関連付けたモデルのレコードに基づいて、モデルのレコードに対するマッチングを絞り込みたい場合もあるでしょう。例えば、最低でも一つのコメントを持つ、全ブログポストを取得したい場合です。これを行うためにはhasメソッドを使用します。When accessing the records for a model, you may wish to limit your results based on the existence of a relationship. For example, you wish to pull all blog posts that have at least one comment. To do so, you may use the has method:

$posts = Post::has('comments')->get();

演算子とレコード数も指定できます。You may also specify an operator and a count:

$posts = Post::has('comments', '>=', 3)->get();

ネストしたhas文は、「ドット」記法で組立てられます。Nested has statements may also be constructed using "dot" notation:

$posts = Post::has('comments.votes')->get();

もっと強力な機能がお望みならば、hasの問い合わせに、"where"で条件をつけるために、whereHasorWhereHasを利用して下さい。If you need even more power, you may use the whereHas and orWhereHas methods to put "where" conditions on your has queries:

$posts = Post::whereHas('comments', function($q)
{
	$q->where('content', 'like', 'foo%');

})->get();

動的プロパティDynamic Properties

Eloquentは動的プロパティーを使用し、関係にアクセスする方法を提供しています。Eloquentは自動的にその関係をロードし、賢いことにget(1対多関係)メソッドとfirst(1対1関係)メソッドを使い分けます。動的プロパティーでアクセスするにはその関係名をメソッド名として使います。例えば、次のPhoneモデルをご覧ください。Eloquent allows you to access your relations via dynamic properties. Eloquent will automatically load the relationship for you, and is even smart enough to know whether to call the get (for one-to-many relationships) or first (for one-to-one relationships) method. It will then be accessible via a dynamic property by the same name as the relation. For example, with the following model $phone:

class Phone extends Model {

	public function user()
	{
		return $this->belongsTo('App\User');
	}

}

$phone = Phone::find(1);

通常、以下のようにメールアドレスをechoします。Instead of echoing the user's email like this:

echo $phone->user()->first()->email;

その代わりに、もっとシンプルで短く記述できます。It may be shortened to simply:

echo $phone->user->email;

複数の結果をリターンするリレーションは、Illuminate\Database\Eloquent\Collectionクラスのインスタンスを返します。Note: Relationships that return many results will return an instance of the Illuminate\Database\Eloquent\Collection class.

EagerローディングEager Loading

EagerローディングはN+1クエリー問題を軽減するために用意しています。例えば、BookモデルがAuthorモデルと関連していると考えてください。関係はこのように定義されます。Eager loading exists to alleviate the N + 1 query problem. For example, consider a Book model that is related to Author. The relationship is defined like so:

class Book extends Model {

	public function author()
	{
		return $this->belongsTo('App\Author');
	}

}

では、次のコードを考察してみましょう。Now, consider the following code:

foreach (Book::all() as $book)
{
	echo $book->author->name;
}

このループでは、まず全ての本をテーブルから取得するために1クエリー実行され、それから著者をそれぞれの本について取得します。ですから、25冊あるならば、このループで26クエリーが発生します。This loop will execute 1 query to retrieve all of the books on the table, then another query for each book to retrieve the author. So, if we have 25 books, this loop would run 26 queries.

ありがたいことに、クエリーの数を徹底的に減らすためにEager(イーガー:熱心な)ローディングを使うことができます。withメソッドを使い、指定してください。Thankfully, we can use eager loading to drastically reduce the number of queries. The relationships that should be eager loaded may be specified via the with method:

foreach (Book::with('author')->get() as $book)
{
	echo $book->author->name;
}

上のループでは、2つだけしかクエリーが実行されません。In the loop above, only two queries will be executed:

select * from books

select * from authors where id in (1, 2, 3, 4, 5, ...)

賢くEagerローディングを使用することで、アプリケーションのパフォーマンスを大幅に向上させることができます。Wise use of eager loading can drastically increase the performance of your application.

もちろん、一度に複数の関係をEagerローディングすることもできます。Of course, you may eager load multiple relationships at one time:

$books = Book::with('author', 'publisher')->get();

ネストした関連でさえ、Eagerローディングできます。You may even eager load nested relationships:

$books = Book::with('author.contacts')->get();

上記では、author関係がEagerローディングされ、それからauthorのcontacts関係がEagerローディングされます。In the example above, the author relationship will be eager loaded, and the author's contacts relation will also be loaded.

Eagerローディングの条件付けEager Load Constraints

関係をEagerローディングする時に、条件を付けたい場合もあります。一例をご覧ください。Sometimes you may wish to eager load a relationship, but also specify a condition for the eager load. Here's an example:

$users = User::with(['posts' => function($query)
{
	$query->where('title', 'like', '%first%');

}])->get();

この例では、ユーザーの写真をEagerローディングしていますが、写真のタイトルが"first"という単語で構成されているものだけが取得されます。In this example, we're eager loading the user's posts, but only if the post's title column contains the word "first".

もちろん、Eagerローディングクロージャーは、「検索条件」指定だけに限定されていません。ソート順も指定できます。Of course, eager loading Closures aren't limited to "constraints". You may also apply orders:

$users = User::with(['posts' => function($query)
{
	$query->orderBy('created_at', 'desc');

}])->get();

遅延EagerローディングLazy Eager Loading

既に存在しているモデルコレクションから直接関係をEagerローディングすることも可能です。これは関係するモデルをロードするかどうかを動的に決める場合や、キャッシュと結びつける場合に便利です。It is also possible to eagerly load related models directly from an already existing model collection. This may be useful when dynamically deciding whether to load related models or not, or in combination with caching.

$books = Book::all();

$books->load('author', 'publisher');

クロージャーでクエリーに制約を設定することもできます。You may also pass a Closure to set constraints on the query:

   $books->load(['author' => function($query)
   {
           $query->orderBy('published_date', 'asc');
   }]);

関連したモデルの挿入Inserting Related Models

関連するモデルを追加するAttaching A Related Model

関連するモデルを新しく挿入する機会も多いと思います。例えば、ポストに対して新しいコメントを挿入する場合です。モデルに外部キーとしてpost_idをセットする代わりに、新しいコメントを親のPostモデルから直接挿入できます。You will often need to insert new related models. For example, you may wish to insert a new comment for a post. Instead of manually setting the post_id foreign key on the model, you may insert the new comment from its parent Post model directly:

$comment = new Comment(['message' => 'A new comment.']);

$post = Post::find(1);

$comment = $post->comments()->save($comment);

この例では、post_idフィールドは自動的にセットされ、コメントが挿入されます。In this example, the post_id field will automatically be set on the inserted comment.

関連するモデルを一度に追加することもできます。If you need to save multiple related models:

$comments = [
	new Comment(['message' => 'A new comment.']),
	new Comment(['message' => 'Another comment.']),
	new Comment(['message' => 'The latest comment.'])
];

$post = Post::find(1);

$post->comments()->saveMany($comments);

関係づけられているモデル(所属)Associating Models (Belongs To)

belongsTo関係を更新する場合、associateメソッドを使用できます。このメソッドは子供のモデルに外部キーをセットします。When updating a belongsTo relationship, you may use the associate method. This method will set the foreign key on the child model:

$account = Account::find(10);

$user->account()->associate($account);

$user->save();

関連したモデルの挿入 (多対多)Inserting Related Models (Many To Many)

多対多の関連を操作する場合も、関連するモデルを挿入したい場合があるでしょう。UserRoleの例を使い、続けて説明します。attachメソッドを使用し、新しい役目をユーザーに追加することができます。You may also insert related models when working with many-to-many relations. Let's continue using our User and Role models as examples. We can easily attach new roles to a user using the attach method:

多対多モデルを追加するAttaching Many To Many Models

$user = User::find(1);

$user->roles()->attach(1);

その関係に対してピボットテーブルに保存する属性の配列を渡すこともできます。You may also pass an array of attributes that should be stored on the pivot table for the relation:

$user->roles()->attach(1, ['expires' => $expires]);

もちろんattachの反対はdetachです。Of course, the opposite of attach is detach:

$user->roles()->detach(1);

attachdetachの両方共に、IDの配列を指定することができます。Both attach and detach also take arrays of IDs as input:

$user = User::find(1);

$user->roles()->detach([1, 2, 3]);

$user->roles()->attach([1 => ['attribute1' => 'value1'], 2, 3]);

多対多モデルの追加にSyncを使用するUsing Sync To Attach Many To Many Models

さらにsyncメソッドで関連するモデルを追加することもできます。syncメソッドはピボットテーブルに設置するIDの配列を渡します。これによる操作が終了すると、そのモデルに対する中間テーブルは配列で指定されたIDだけになります。You may also use the sync method to attach related models. The sync method accepts an array of IDs to place on the pivot table. After this operation is complete, only the IDs in the array will be on the intermediate table for the model:

$user->roles()->sync([1, 2, 3]);

Syncを使い、ピボットデーターを追加するAdding Pivot Data When Syncing

IDを指定して他のピボットテーブル値を関連付けることもできます。You may also associate other pivot table values with the given IDs:

$user->roles()->sync([1 => ['expires' => true]]);

時にはひとつのコマンドで、関連するモデルを作成し、追加したいこともあるでしょう。その場合、saveメソッドを使用してください。Sometimes you may wish to create a new related model and attach it in a single command. For this operation, you may use the save method:

$role = new Role(['name' => 'Editor']);

User::find(1)->roles()->save($role);

この例では、新しいRoleモデルは保存され、ユーザーモデルに結び付けられます。更に以下の操作で、関連するテーブルに設定する属性の配列を渡すことができます。In this example, the new Role model will be saved and attached to the user model. You may also pass an array of attributes to place on the joining table for this operation:

User::find(1)->roles()->save($role, ['expires' => $expires]);

親のタイムスタンプの更新Touching Parent Timestamps

例えばCommentPostに所属しているような場合、子供のモデルが変更された場合、所属している(belongsTo)親のタイムスタンプも変更されると便利です。Commentモデルが更新されたら、Postが持っているupdated_atタイムスタンプも自動的に更新したい場合などです。Eloquentでは簡単に実現できます。子供のモデルでtouchesプロパティーに、関連名を付け加えてください。When a model belongsTo another model, such as a Comment which belongs to a Post, it is often helpful to update the parent's timestamp when the child model is updated. For example, when a Comment model is updated, you may want to automatically touch the updated_at timestamp of the owning Post. Eloquent makes it easy. Just add a touches property containing the names of the relationships to the child model:

class Comment extends Model {

	protected $touches = ['post'];

	public function post()
	{
		return $this->belongsTo('App\Post');
	}

}

これで、Postに所有されているCommentが更新されると、Postupdated_atカラムも更新されるようになります。Now, when you update a Comment, the owning Post will have its updated_at column updated:

$comment = Comment::find(1);

$comment->text = 'このコメントを変更!';

$comment->save();

ピボットテーブルの操作Working With Pivot Tables

既に学んだように、多対多の関連を操作するためには中間テーブルが必要です。Eloquentはこのテーブルを操作するために役に立つ手法も提供しています。例えば、Userオブジェクトが多くの関連するRoleオブジェクトを所有しているとしましょう。この関連にアクセスした後に、モデルに対するピボット(pivot)テーブルにもアクセスできます。As you have already learned, working with many-to-many relations requires the presence of an intermediate table. Eloquent provides some very helpful ways of interacting with this table. For example, let's assume our User object has many Role objects that it is related to. After accessing this relationship, we may access the pivot table on the models:

$user = User::find(1);

foreach ($user->roles as $role)
{
	echo $role->pivot->created_at;
}

取得されたRoleモデルそれぞれは、自動的にpivot属性を与えられていることに注目してください。この属性は中間テーブルを表すモデルで、他のEloquentモデルと同様に使用できます。Notice that each Role model we retrieve is automatically assigned a pivot attribute. This attribute contains a model representing the intermediate table, and may be used as any other Eloquent model.

デフォルトでは、pivotオブジェクトにはキーしかありません。もし、あなたのピボットテーブルにその他の属性があるのでしたら、関連を定義する時にそれを指定する必要があります。By default, only the keys will be present on the pivot object. If your pivot table contains extra attributes, you must specify them when defining the relationship:

return $this->belongsToMany('App\Role')->withPivot('foo', 'bar');

これでRoleモデルのpivotオブジェクトで、foobar属性がアクセス可能になります。Now the foo and bar attributes will be accessible on our pivot object for the Role model.

もしピボットテーブルでも自動的にcreated_atupdated_atタイムスタンプを更新したい場合は、関係の定義にwithTimestampsメソッドを使用してください。If you want your pivot table to have automatically maintained created_at and updated_at timestamps, use the withTimestamps method on the relationship definition:

return $this->belongsToMany('App\Role')->withTimestamps();

Pivotテーブルのレコード削除Deleting Records On A Pivot Table

モデルのピボットテーブルの全レコードを削除したい場合は、detachメソッドを使用してください。To delete all records on the pivot table for a model, you may use the detach method:

User::find(1)->roles()->detach();

この操作はrolesテーブルからレコードを削除せず、ピボットテーブルに対してだけ操作されることに注目してください。Note that this operation does not delete records from the roles table, but only from the pivot table.

ピボットテーブル上のレコード更新Updating A Record On A Pivot Table

場合により、ピボットテーブルを削除せずに、更新する必要があることもあるでしょう。存在するピボットテーブルを更新したい場合は、updateExistingPivotメソッドが使用できます。Sometimes you may need to update your pivot table, but not detach it. If you wish to update your pivot table in place you may use updateExistingPivot method like so:

User::find(1)->roles()->updateExistingPivot($roleId, $attributes);

カスタムピボットモデルの定義Defining A Custom Pivot Model

Laravelではカスタムピボットモデルを定義することさえできます。カスタムモデルを定義するためには、最初にEloquentを拡張したBaseモデルクラスを作成します。そして他のEloquentモデルでは、デフォルトのEloquentの代わりに、このカスタムベースモデルを拡張しましょう。ベースモデルの中に、カスタムピボットモデルのインスタンスを返す、次のような関数を追加してください。Laravel also allows you to define a custom Pivot model. To define a custom model, first create your own "Base" model class that extends Eloquent. In your other Eloquent models, extend this custom base model instead of the default Eloquent base. In your base model, add the following function that returns an instance of your custom Pivot model:

public function newPivot(Model $parent, array $attributes, $table, $exists)
{
	return new YourCustomPivot($parent, $attributes, $table, $exists);
}

コレクションCollections

getメソッドであれ、関連によるものであれ、Eloquentが複数のレコードをリターンする場合、Eloquent Collectionオブジェクトが返されます。このオブジェクトはIteratorAggregate PHPインターフェイスの実装で、そのため配列のように操作できます。更に、結果を操作するためのバラエティーに富んだ他のパワフルなメソッドも持っています。All multi-result sets returned by Eloquent, either via the get method or a relationship, will return a collection object. This object implements the IteratorAggregate PHP interface so it can be iterated over like an array. However, this object also has a variety of other helpful methods for working with result sets.

特定のキーをコレクションに含んでいるか調べる。Checking If A Collection Contains A Key

例えば、containsメソッドを使用し、指定した主キーを結果に含んでいるか調べることができます。For example, we may determine if a result set contains a given primary key using the contains method:

$roles = User::find(1)->roles;

if ($roles->contains(2))
{
	//
}

コレクションは配列やJSONに変換することもできます。Collections may also be converted to an array or JSON:

$roles = User::find(1)->roles->toArray();

$roles = User::find(1)->roles->toJson();

コレクションを文字列にキャストすると、JSONがリターンされます。If a collection is cast to a string, it will be returned as JSON:

$roles = (string) User::find(1)->roles;

コレクションの反復処理Iterating Collections

Eloquentコレクションは、中に含んでいるアイテムをループしたり、フィルタリングしたりする便利なメソッドも持っています。Eloquent collections also contain a few helpful methods for looping and filtering the items they contain:

$roles = $user->roles->each(function($role)
{
	//
});

コレクションのフィルタリングFiltering Collections

コレクションをフィルタリングする場合、指定されたコールバックは、array_filterのコールバックとして利用されます。When filtering collections, the callback provided will be used as callback for array_filter[http://php.net/manual/en/function.array-filter.php].

$users = $users->filter(function($user)
{
	return $user->isAdmin();
});

**注目:**コレクションをフィルタリングするか、JSONに変換する場合、valuesメソッドを最初に呼び出し、配列のキーをリセットしてください。Note: When filtering a collection and converting it to JSON, try calling the values function first to reset the array's keys.

コレクションの各オブジェクトにコールバックを適用Applying A Callback To Each Collection Object

$roles = User::find(1)->roles;

$roles->each(function($role)
{
	//
});

値でコレクションのソートSorting A Collection By A Value

$roles = $roles->sortBy(function($role)
{
	return $role->created_at;
});

$roles = $roles->sortByDesc(function($role)
{
	return $role->created_at;
});

値でコレクションのソートSorting A Collection By A Value

$roles = $roles->sortBy('created_at');

$roles = $roles->sortByDesc('created_at');

カスタムコレクションタイプの返却Returning A Custom Collection Type

カスタムメソッドをつけた、カスタムコレクションオブジェクトをリターンしたい場合もあるでしょう。EloquentモデルのnewCollectionメソッドをオーバーライドしてください。Sometimes, you may wish to return a custom Collection object with your own added methods. You may specify this on your Eloquent model by overriding the newCollection method:

class User extends Model {

	public function newCollection(array $models = [])
	{
		return new CustomCollection($models);
	}

}

アクセサーとミューテーターAccessors & Mutators

アクセサーの定義Defining An Accessor

Eloquentはモデルの属性を設定したり取得したりする時に、内容を変更できる便利な方法を提供しています。モデルのアクセサーを宣言するには、getFooAttributeメソッドを定義するだけです。データベースのカラムがスネークケースであったとしても、メソッドはキャメルケースにしなくてはならないことに注意してください。Eloquent provides a convenient way to transform your model attributes when getting or setting them. Simply define a getFooAttribute method on your model to declare an accessor. Keep in mind that the methods should follow camel-casing, even though your database columns are snake-case:

class User extends Model {

	public function getFirstNameAttribute($value)
	{
		return ucfirst($value);
	}

}

上記の例は、first_nameカラムのアクセサーです。アクセサーに属性の値を渡していることに注目してください。In the example above, the first_name column has an accessor. Note that the value of the attribute is passed to the accessor.

ミューテーターの定義Defining A Mutator

ミューテーターも同じやり方で定義します。Mutators are declared in a similar fashion:

class User extends Model {

	public function setFirstNameAttribute($value)
	{
		$this->attributes['first_name'] = strtolower($value);
	}

}

日付ミューテーターDate Mutators

デフォルトでEloquentはcreated_at、updated_atカラムを Carbonのインスタンスに変換します。Carbonは便利なメソッドが揃っており、PHPネイティブのDateTimeクラスを拡張しています。By default, Eloquent will convert the created_at and updated_at columns to instances of Carbon[https://github.com/briannesbitt/Carbon], which provides an assortment of helpful methods, and extends the native PHP DateTime class.

これらのフィールドの自動変換をカスタマイズ、またはこの変換を完全に無効にすることも、モデルのgetDatesメソッドをオーバーライドすることで可能です。You may customize which fields are automatically mutated, and even completely disable this mutation, by overriding the getDates method of the model:

public function getDates()
{
	return ['created_at'];
}

日付項目にはUNIXタイムスタンプ、日付文字列(Y-m-d)、日付時間文字列、そしてもちろんDateTimeCarbonのインスタンスを設定することができます。When a column is considered a date, you may set its value to a UNIX timestamp, date string (Y-m-d), date-time string, and of course a DateTime / Carbon instance.

日付ミューテーターを完全に無効にしたい場合は、getDatesメソッドから空配列をリターンしてください。To totally disable date mutations, simply return an empty array from the getDates method:

public function getDates()
{
	return [];
}

属性の型変換Attribute Casting

常に他のデータ型へ型変換したい属性がある場合、モデルのcastsプロパティーへ属性を追加してください。もしくは、手間がかかりますが各属性をミューテターでそれぞれ定義してください。castsプロパティの使用例をご覧ください。If you have some attributes that you want to always convert to another data-type, you may add the attribute to the casts property of your model. Otherwise, you will have to define a mutator for each of the attributes, which can be time consuming. Here is an example of using the casts property:

/**
 * ネイティブなタイプへ型変換しなくてはならない属性
 *
 * @var array
 */
protected $casts = [
	'is_admin' => 'boolean',
];

これで、データベース上では整数として値が保存されていても、is_admin属性にアクセスすれば、いつも論理型へ型変換されます。サポートしている変換型は、integerrealfloatdoublestringbooleanobjectarrayです。Now the is_admin attribute will always be cast to a boolean when you access it, even if the underlying value is stored in the database as an integer. Other supported cast types are: integer, real, float, double, string, boolean, object and array.

array型変換はシリアライズ済みのJSONとして保存されているカラムに利用すると特に便利です。例えば、データベースにシリアライズされたJSONがTEXTタイプのフィールドにある時、array型変換を指定しておけば、そのEloquentモデルへアクセすると、属性がPHP配列へ自動的に非シリアライズされます。The array cast is particularly useful for working with columns that are stored as serialized JSON. For example, if your database has a TEXT type field that contains serialized JSON, adding the array cast to that attribute will automatically deserialize the attribute to a PHP array when you access it on your Eloquent model:

/**
 * ネイティブなタイプへ型変換しなくてはならない属性
 *
 * @var array
 */
protected $casts = [
	'options' => 'array',
];

これで、Eloquentモデルを使用します。Now, when you utilize the Eloquent model:

$user = User::find(1);

// $optionsは配列…
$options = $user->options;

// optionsは自動的にJSONに戻される…
$user->options = ['foo' => 'bar'];

モデルイベントModel Events

Eloquentモデルは多くのイベントを発行します。以降のメソッドを利用し、モデルのライフサイクルの様々な時点をフックすることができます:creatingcreatedupdatingupdatedsavingsaveddeletingdeletedrestoringrestoredEloquent models fire several events, allowing you to hook into various points in the model's lifecycle using the following methods: creating, created, updating, updated, saving, saved, deleting, deleted, restoring, restored.

いつでも新しいアイテムが最初に保存される場合に、creatingcreatedイベントが発行されます。新しくないアイテムにsaveメソッドが呼び出されると、updatingupdatedイベントが発行されます。どちらの場合にも、savingsavedイベントは発行されます。Whenever a new item is saved for the first time, the creating and created events will fire. If an item is not new and the save method is called, the updating / updated events will fire. In both cases, the saving / saved events will fire.

イベントにより保存操作をキャンセルするCancelling Save Operations Via Events

もし、creatingupdatingsavingdeletingイベントでfalseがリターンされると、そのアクションはキャンセルされます。If false is returned from the creating, updating, saving, or deleting events, the action will be cancelled:

User::creating(function($user)
{
	if ( ! $user->isValid()) return false;
});

イベントリスナーを登録する場所Where To Register Event Listeners

EventServiceProviderはモデルのイベント結合を登録するため、便利に使えます。例をご覧ください。Your EventServiceProvider serves as a convenient place to register your model event bindings. For example:

/**
 * アプリケーションの他のイベントを登録する
 *
 * @param  \Illuminate\Contracts\Events\Dispatcher  $events
 * @return void
 */
public function boot(DispatcherContract $events)
{
	parent::boot($events);

	User::creating(function($user)
	{
		//
	});
}

モデルオブザーバーModel Observers

モデルのイベントを取りまとめるにはモデルオブザーバーを登録してください。オブザーバークラスは対応するそれぞれのモデルイベントのメソッドを用意します。例えば、監視するのがcreatingupdatingsavingイベントなら、その名前のメソッドを用意します。もちろん他のモデルイベント名も追加できます。To consolidate the handling of model events, you may register a model observer. An observer class may have methods that correspond to the various model events. For example, creating, updating, saving methods may be on an observer, in addition to any other model event name.

ですから、モデルオブザーバーは次のような形式になります。So, for example, a model observer might look like this:

class UserObserver {

	public function saving($model)
	{
		//
	}

	public function saved($model)
	{
		//
	}

}

オブザーバーのインスタンスはobserveメソッドを使い、モデルへ登録してください。You may register an observer instance using the observe method:

User::observe(new UserObserver);

モデルURL生成Model URL Generation

routeactionメソッドへモデルを渡すと、生成されるURIに主キーの値が挿入されます。例で確認してください。When you pass a model to the route or action methods, it's primary key is inserted into the generated URI. For example:

   Route::get('user/{user}', 'UserController@show');

   action('UserController@show', [$user]);

この場合、$user->idプロパティが、生成されるURLの{user}プレースフォルダー部分へ挿入されます。しかし、他のプロパティーをIDとして挿入したければ、モデルのgetRouteKeyメソッドをオーバーライドしてください。In this example the $user->id property will be inserted into the {user} place-holder of the generated URL. However, if you would like to use another property instead of the ID, you may override the getRouteKey method on your model:

public function getRouteKey()
{
	return $this->slug;
}

配列とJSONへの変換Converting To Arrays / JSON

モデルを配列に変換Converting A Model To An Array

JSONでAPIを作成する場合、モデルと関連をしばしば配列やJSONに変換する必要が起きます。そのため、Eloquentはこれを行うメソッドを含んでいます。モデルとそれにロードされている関連を配列に変換するには、toArrayメソッドが使用できます。When building JSON APIs, you may often need to convert your models and relationships to arrays or JSON. So, Eloquent includes methods for doing so. To convert a model and its loaded relationship to an array, you may use the toArray method:

$user = User::with('roles')->first();

return $user->toArray();

モデルの全コレクションを配列に変換することさえできることに注目してください。Note that entire collections of models may also be converted to arrays:

return User::all()->toArray();

モデルをJSONに変換Converting A Model To JSON

モデルをJSONに変換するには、toJsonメソッドを使用します。To convert a model to JSON, you may use the toJson method:

return User::find(1)->toJson();

ルーティングからの返却Returning A Model From A Route

モデルやコレクションを文字列に変換する場合、JSON形式に変換されることに注目してください。これが意味するのはEloquentオブジェクトを直接アプリケーションのルートからリターンできるということです!Note that when a model or collection is cast to a string, it will be converted to JSON, meaning you can return Eloquent objects directly from your application's routes!

Route::get('users', function()
{
	return User::all();
});

配列とJSONへの変換から特定の属性を除くHiding Attributes From Array Or JSON Conversion

パスワードのように、モデルの配列やJSON形式に含める属性を制限したい属性もあります。そのためにはhiddenプロパティーをモデルで定義してください。Sometimes you may wish to limit the attributes that are included in your model's array or JSON form, such as passwords. To do so, add a hidden property definition to your model:

class User extends Model {

	protected $hidden = ['password'];

}

注意: リレーションを隠す場合、動的なアクセサー名を使用せずに、リレーションのメソッド名を使用してください。Note: When hiding relationships, use the relationship's method name, not the dynamic accessor name.

反対に、visibleプロパティでホワイトリストを定義することもできます。Alternatively, you may use the visible property to define a white-list:

protected $visible = ['first_name', 'last_name'];

時にはデーターベースのカラムに対応していない属性を追加する必要もあるでしょう。これを行うには、先ず値を返すアクセサーを定義してください。

public function getIsAdminAttribute()
{
	return $this->attributes['admin'] == 'yes';
}

アクセサーを作成したら、モデルのappendsプロパティーにその値を追加してください。Once you have created the accessor, just add the value to the appends property on the model:

protected $appends = ['is_admin'];

属性をappendsリストに追加すると、モデルの配列とJSON形式の両方へ含まれるようになります。appends配列の属性は、モデル中のvisiblehidden設定の影響を受けます。Once the attribute has been added to the appends list, it will be included in both the model's array and JSON forms. Attributes in the appends array respect the visible and hidden configuration on the model.

章選択

Artisan CLI

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作