Commit b5e75f6f authored by Taylor Otwell's avatar Taylor Otwell

Fixing bugs and improving.

Signed-off-by: 's avatarTaylor Otwell <taylorotwell@gmail.com>
parent dc92dd26
...@@ -82,6 +82,13 @@ abstract class Model { ...@@ -82,6 +82,13 @@ abstract class Model {
*/ */
public static $sequence; public static $sequence;
/**
* The default number of models to show per page when paginating.
*
* @var int
*/
public static $per_page = 20;
/** /**
* Create a new Eloquent model instance. * Create a new Eloquent model instance.
* *
...@@ -150,6 +157,23 @@ abstract class Model { ...@@ -150,6 +157,23 @@ abstract class Model {
return $this; return $this;
} }
/**
* Create a new model and store it in the database.
*
* If save is successful, the model will be returned, otherwise false.
*
* @param array $attributes
* @return Model|false
*/
public static function create($attributes)
{
$model = new static($attributes);
$success = $model->save();
return ($success) ? $model : false;
}
/** /**
* Find a model by its primary key. * Find a model by its primary key.
* *
...@@ -320,7 +344,7 @@ abstract class Model { ...@@ -320,7 +344,7 @@ abstract class Model {
*/ */
protected function timestamp() protected function timestamp()
{ {
$this->updated_at = static::get_timestamp(); $this->updated_at = $this->get_timestamp();
if ( ! $this->exists) $this->created_at = $this->updated_at; if ( ! $this->exists) $this->created_at = $this->updated_at;
} }
...@@ -330,7 +354,7 @@ abstract class Model { ...@@ -330,7 +354,7 @@ abstract class Model {
* *
* @return mixed * @return mixed
*/ */
protected static function get_timestamp() public function get_timestamp()
{ {
return date('Y-m-d H:i:s'); return date('Y-m-d H:i:s');
} }
...@@ -502,7 +526,7 @@ abstract class Model { ...@@ -502,7 +526,7 @@ abstract class Model {
// If the method is actually the name of a static property on the model we'll // If the method is actually the name of a static property on the model we'll
// return the value of the static property. This makes it convenient for // return the value of the static property. This makes it convenient for
// relationships to access these values off of the instances. // relationships to access these values off of the instances.
if (in_array($method, array('key', 'table', 'connection', 'sequence'))) if (in_array($method, array('key', 'table', 'connection', 'sequence', 'per_page')))
{ {
return static::$$method; return static::$$method;
} }
......
...@@ -9,6 +9,13 @@ class Pivot extends Model { ...@@ -9,6 +9,13 @@ class Pivot extends Model {
*/ */
public $pivot_table; public $pivot_table;
/**
* Indicates if the model has update and creation timestamps.
*
* @var bool
*/
public static $timestamps = true;
/** /**
* Create a new pivot table instance. * Create a new pivot table instance.
* *
......
...@@ -29,8 +29,8 @@ class Query { ...@@ -29,8 +29,8 @@ class Query {
* @var array * @var array
*/ */
public $passthru = array( public $passthru = array(
'lists', 'only', 'insert', 'update', 'increment', 'decrement', 'lists', 'only', 'insert', 'insert_get_id', 'update', 'increment',
'count', 'min', 'max', 'avg', 'sum' 'decrement', 'count', 'min', 'max', 'avg', 'sum',
); );
/** /**
...@@ -68,33 +68,28 @@ class Query { ...@@ -68,33 +68,28 @@ class Query {
*/ */
public function get($columns = array('*'), $include = true) public function get($columns = array('*'), $include = true)
{ {
$results = $this->hydrate($this->model, $this->table->get($columns)); return $this->hydrate($this->model, $this->table->get($columns), $include);
}
if ($include) /**
{ * Get an array of paginated model results.
foreach ($this->model_includes() as $relationship => $constraints) *
{ * @param int $per_page
// If the relationship is nested, we will skip laoding it here and let * @param array $columns
// the load method parse and set the nested eager loads on the right * @return Paginator
// relationship when it is getting ready to eager laod. */
if (str_contains($relationship, '.')) public function paginate($per_page = null, $columns = array('*'))
{ {
continue; $per_page = $per_page ?: $this->model->per_page();
}
$this->load($results, $relationship, $constraints); // First we'll grab the Paginator instance and get the results. Then we can
} // feed those raw database results into the hydrate method to get models
} // for the results, which we'll set on the paginator and return it.
$paginator = $this->table->paginate($per_page, $columns);
// The many to many relationships may have pivot table column on them $paginator->results = $this->hydrate($this->model, $paginator->results);
// so we will call the "clean" method on the relationship to remove
// any pivot columns that are on the model.
if ($this instanceof Relationships\Has_Many_And_Belongs_To)
{
$this->pivot($results);
}
return $results; return $paginator;
} }
/** /**
...@@ -104,7 +99,7 @@ class Query { ...@@ -104,7 +99,7 @@ class Query {
* @param array $results * @param array $results
* @return array * @return array
*/ */
public function hydrate($model, $results) public function hydrate($model, $results, $include = true)
{ {
$class = get_class($model); $class = get_class($model);
...@@ -120,6 +115,30 @@ class Query { ...@@ -120,6 +115,30 @@ class Query {
$models[$result[$this->model->key()]] = new $class($result, true); $models[$result[$this->model->key()]] = new $class($result, true);
} }
if ($include and count($results) > 0)
{
foreach ($this->model_includes() as $relationship => $constraints)
{
// If the relationship is nested, we will skip laoding it here and let
// the load method parse and set the nested eager loads on the right
// relationship when it is getting ready to eager laod.
if (str_contains($relationship, '.'))
{
continue;
}
$this->load($models, $relationship, $constraints);
}
}
// The many to many relationships may have pivot table column on them
// so we will call the "clean" method on the relationship to remove
// any pivot columns that are on the model.
if ($this instanceof Relationships\Has_Many_And_Belongs_To)
{
$this->pivot($models);
}
return $models; return $models;
} }
......
...@@ -23,7 +23,7 @@ class Has_Many_And_Belongs_To extends Relationship { ...@@ -23,7 +23,7 @@ class Has_Many_And_Belongs_To extends Relationship {
* *
* @var array * @var array
*/ */
protected $with = array(); protected $with = array('created_at', 'updated_at');
/** /**
* Create a new many to many relationship instance. * Create a new many to many relationship instance.
...@@ -73,25 +73,29 @@ class Has_Many_And_Belongs_To extends Relationship { ...@@ -73,25 +73,29 @@ class Has_Many_And_Belongs_To extends Relationship {
/** /**
* Insert a new record into the joining table of the association. * Insert a new record into the joining table of the association.
* *
* @param int $id * @param int $id
* @param array $joining
* @return bool * @return bool
*/ */
public function add($id) public function add($id, $attributes = array())
{ {
return $this->insert_joining($this->join_record($id)); $joining = array_merge($this->join_record($id), $attributes);
return $this->insert_joining($joining);
} }
/** /**
* Insert a new record for the association. * Insert a new record for the association.
* *
* @param array $attributes * @param array $attributes
* @param array $joining
* @return bool * @return bool
*/ */
public function insert($attributes) public function insert($attributes, $joining = array())
{ {
$id = $this->table->insert_get_id($attributes, $this->model->sequence()); $id = $this->table->insert_get_id($attributes, $this->model->sequence());
$result = $this->insert_joining($this->join_record($id)); $result = $this->insert_joining(array_merge($this->join_record($id), $joining));
return is_numeric($id) and $result; return is_numeric($id) and $result;
} }
...@@ -125,6 +129,13 @@ class Has_Many_And_Belongs_To extends Relationship { ...@@ -125,6 +129,13 @@ class Has_Many_And_Belongs_To extends Relationship {
*/ */
protected function insert_joining($attributes) protected function insert_joining($attributes)
{ {
// All joining tables get creation and update timestamps automatically even though
// some developers may not need them. This just provides them if necessary since
// it would be a pain for the developer to maintain them manually.
$attributes['created_at'] = $this->model->get_timestamp();
$attributes['updated_at'] = $attributes['created_at'];
return $this->joining_table()->insert($attributes); return $this->joining_table()->insert($attributes);
} }
...@@ -292,7 +303,12 @@ class Has_Many_And_Belongs_To extends Relationship { ...@@ -292,7 +303,12 @@ class Has_Many_And_Belongs_To extends Relationship {
*/ */
public function with($columns) public function with($columns)
{ {
$this->with = (is_array($columns)) ? $columns : func_get_args(); $columns = (is_array($columns)) ? $columns : func_get_args();
// The "with" array contains a couple of columns by default, so we will
// just merge in the developer specified columns here, and we'll make
// sure the values of the array are unique.
$this->with = array_unique(array_merge($this->with, $columns));
$this->set_select($this->foreign_key(), $this->other_key()); $this->set_select($this->foreign_key(), $this->other_key());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment