时间:2021-07-01 10:21:17 帮助过:7人阅读
Note that we did not tell ORM which table to use for our User model. The lower-case, plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, ORM 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 \Database\ORM\Model {
protected $table = ‘my_users‘;
}
Note: ORM 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.
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.
$users = User::all();
$user = User::find(1);
var_dump($user->name);
Note: All methods available on the QueryBuilder are also available when querying ORM models.
Sometimes you may wish to throw an exception if a model is not found, allowing you to catch the exceptions using an App::error handler and display a 404 page.
$model = User::findOrFail(1);
$model = User::where(‘votes‘, ‘>‘, 100)->firstOrFail();
To register the error handler, listen for the ModelNotFoundException
use Illuminate\Database\ORM\ModelNotFoundException;
App::error(function(ModelNotFoundException $e)
{
return Response::make(‘Not Found‘, 404);
});
$users = User::where(‘votes‘, ‘>‘, 100)->take(10)->get();
foreach ($users as $user)
{
var_dump($user->name);
}
Of course, you may also use the query builder aggregate functions.
$count = User::where(‘votes‘, ‘>‘, 100)->count();
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‘, array(25))->get();
If you need to process a lot (thousands) of ORM 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)
{
//
}
});
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.
You may also specify which database connection should be used when running an ORM query. Simply use the on method:
$user = User::on(‘connection-name‘)->find(1);
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 ORM models protect against mass-assignment by default.
To get started, set the fillable or guarded properties on your model.
The fillable property specifies which attributes should be mass-assignable. This can be set at the class or instance level.
class User extends \Database\ORM\Model {
protected $fillable = array(‘first_name‘, ‘last_name‘, ‘email‘);
}
In this example, only the three listed attributes will be mass-assignable.
The inverse of fillable is guarded, and serves as a "black-list" instead of a "white-list":
class User extends \Database\ORM\Model {
protected $guarded = array(‘id‘, ‘password‘);
}
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.
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 = array(‘*‘);
To create a new record in the database from a model, simply create a new model instance and call the save method.
$user = new User;
$user->name = ‘John‘;
$user->save();
Note: Typically, your ORM models will have auto-incrementing keys. However, if you wish to specify your own keys, set the incrementing property on your model to false.
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 ORM models protect against mass-assignment.
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;
class User extends \Database\ORM\Model {
protected $guarded = array(‘id‘, ‘account_id‘);
}
// Create a new user in the database...
$user = User::create(array(‘name‘ => ‘John‘));
// Retrieve the user by the attributes, or create it if it doesn‘t exist...
$user = User::firstOrCreate(array(‘name‘ => ‘John‘));
// Retrieve the user by the attributes, or instantiate a new instance...
$user = User::firstOrNew(array(‘name‘ => ‘John‘));
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();
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(array(‘status‘ => 2));
To delete a model, simply call the delete method on the instance:
$user = User::find(1);
$user->delete();
User::destroy(1);
User::destroy(array(1, 2, 3));
User::destroy(1, 2, 3);
Of course, you may also run a delete query on a set of models:
$affectedRows = User::where(‘votes‘, ‘>‘, 100)->delete();
If you wish to simply update the timestamps on a model, you may use the touch method:
$user->touch();
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, specify the softDelete property on the model:
class User extends \Database\ORM\Model {
protected $softDelete = true;
}
To add a deleted_at column to your table, you may use the softDeletes method from a migration:
$table->softDeletes();
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.
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();
The withTrashed method may be used on a defined relationship:
$user->posts()->withTrashed()->get();
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();
To restore a soft deleted model into an active state, use the restore method:
$user->restore();
You may also use the restore method on a query:
User::withTrashed()->where(‘account_id‘, 1)->restore();
Like with withTrashed, the restore method may also be used on relationships:
$user->posts()->restore();
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();
To determine if a given model instance has been soft deleted, you may use the trashed method:
if ($user->trashed())
{
//
}
By default, ORM will maintain the created_at and updated_at columns on your database table automatically. Simply add these timestamp columns to your table and ORM will take care of the rest. If you do not wish for ORM to maintain these columns, add the following property to your model:
class User extends \Database\ORM\Model {
protected $table = ‘users‘;
public $timestamps = false;
}
If you wish to customize the format of your timestamps, you may override the getDateFormat method in your model:
class User extends \Database\ORM\Model {
protected function getDateFormat()
{
return ‘U‘;
}
}
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 \Database\ORM\Model {
public function scopePopular($query)
{
return $query->where(‘votes‘, ‘>‘, 100);
}
public function scopeWomen($query)
{
return $query->whereGender(‘W‘);
}
}
$users = User::popular()->women()->orderBy(‘created_at‘)->get();
Sometimes You may wish to define a scope that accepts parameters. Just add your parameters to your scope function:
class User extends \Database\ORM\Model {
public function scopeOfType($query, $type)
{
return $query->whereType($type);
}
}
Then pass the parameter into the scope call:
$users = User::ofType(‘member‘)->get();
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. ORM makes managing and working with these relationships easy. Nova Framework supports many types of relationships:
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 ORM:
class User extends \Database\ORM\Model {
public function phone()
{
return $this->hasOne(‘Phone‘);
}
}
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 ORM‘s dynamic properties:
$phone = User::find(1)->phone;
The SQL performed by this statement will be as follows:
select * from users where id = 1
select * from phones where user_id = 1
Take note that ORM 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(‘Phone‘, ‘foreign_key‘);
return $this->hasOne(‘Phone‘, ‘foreign_key‘, ‘local_key‘);
To define the inverse of the relationship on the Phone model, we use the belongsTo method:
class Phone extends \Database\ORM\Model {
public function user()
{
return $this->belongsTo(‘User‘);
}
}
In the example above, ORM 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 \Database\ORM\Model {
public function user()
{
return $this->belongsTo(‘User‘, ‘local_key‘);
}
}
Additionally, you pass a third parameter which specifies the name of the associated column on the parent table:
class Phone extends \Database\ORM\Model {
public function user()
{
return $this->belongsTo(‘User‘, ‘local_key‘, ‘parent_key‘);
}
}
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 \Database\ORM\Model {
public function comments()
{
return $this->hasMany(‘Comment‘);
}
}
Now we can access the post‘s comments through the dynamic property:
$comments = Post::find(1)->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();
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(‘Comment‘, ‘foreign_key‘);
return $this->hasMany(‘Comment‘, ‘foreign_key‘, ‘local_key‘);
To define the inverse of the relationship on the Comment model, we use the belongsTo method:
class Comment extends \Database\ORM\Model {
public function post()
{
return $this->belongsTo(‘Post‘);
}
}
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.
We can define a many-to-many relation using the belongsToMany method:
class User extends \Database\ORM\Model {
public function roles()
{
return $this->belongsToMany(‘Role‘);
}
}
Now, we can retrieve the roles through the User model:
$roles = User::find(1)->roles;
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(‘Role‘, ‘user_roles‘);
You may also override the conventional associated keys:
return $this->belongsToMany(‘Role‘, ‘user_roles‘, ‘user_id‘, ‘foo_id‘);
Of course, you may also define the inverse of the relationship on the Role model:
class Role extends \Database\ORM\Model {
public function users()
{
return $this->belongsToMany(‘User‘);
}
}
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 Posts through a Users 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
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 \Database\ORM\Model {
public function posts()
{
return $this->hasManyThrough(‘Post‘, ‘User‘);
}
}
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 \Database\ORM\Model {
public function posts()
{
return $this->hasManyThrough(‘Post‘, ‘User‘, ‘country_id‘, ‘user_id‘);
}
}
Polymorphic relations allow a model to belong to more than one