src/Eloquent/Model.php
<?php
namespace duxet\Rethinkdb\Eloquent;
use Carbon\Carbon;
use DateTime;
use duxet\Rethinkdb\Eloquent\Relations\BelongsTo;
use duxet\Rethinkdb\Query\Builder as QueryBuilder;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
class Model extends \Illuminate\Database\Eloquent\Model
{
/**
* The "type" of the auto-incrementing ID.
* Setting to 'string' prevents Laravel from casting non-integer IDs
* to numeric ones. Very helpful with inverted relations.
*
* @var string
*/
protected $keyType = 'string';
/**
* Get the format for database stored dates.
*
* @return string
*/
public function getDateFormat()
{
return $this->dateFormat ?: 'Y-m-d H:i:s';
}
/**
* Get the table qualified key name.
*
* @return string
*/
public function getQualifiedKeyName()
{
return $this->getKeyName();
}
/**
* Ensure Timestamps are returned in DateTime.
*
* @param \DateTime $value
*
* @return \DateTime
*/
protected function asDateTime($value)
{
// Legacy support for Laravel 5.0
if (!$value instanceof Carbon) {
return Carbon::instance($value);
}
return parent::asDateTime($value);
}
/**
* Retain DateTime format for storage.
*
* @param \DateTime $value
*
* @return string
*/
public function fromDateTime($value)
{
if ($value instanceof DateTime) {
return $value;
}
return parent::asDateTime($value);
}
/**
* Get a new query builder instance for the connection.
*
* @return Builder
*/
protected function newBaseQueryBuilder()
{
$connection = $this->getConnection();
// Check the connection type
if ($connection instanceof \duxet\Rethinkdb\Connection) {
return new QueryBuilder($connection);
}
return parent::newBaseQueryBuilder();
}
/**
* Create a new Eloquent query builder for the model.
*
* @param \duxet\Rethinkdb\Query\Builder $query
*
* @return \duxet\Rethinkdb\Eloquent\Builder|static
*/
public function newEloquentBuilder($query)
{
return new Builder($query);
}
/**
* Define an inverse one-to-one or many relationship.
*
* @param string $related
* @param string $foreignKey
* @param string $otherKey
* @param string $relation
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null)
{
// If no relation name was given, we will use this debug backtrace to extract
// the calling method's name and use that as the relationship name as most
// of the time this will be what we desire to use for the relationships.
if (is_null($relation)) {
list(, $caller) = debug_backtrace(false, 2);
$relation = $caller['function'];
}
// If no foreign key was supplied, we can use a backtrace to guess the proper
// foreign key name by using the name of the relationship function, which
// when combined with an "_id" should conventionally match the columns.
if (is_null($foreignKey)) {
$foreignKey = snake_case($relation).'_id';
}
$instance = new $related();
// Once we have the foreign key names, we'll just create a new Eloquent query
// for the related models and returns the relationship instance which will
// actually be responsible for retrieving and hydrating every relations.
$query = $instance->newQuery();
$otherKey = $otherKey ?: $instance->getKeyName();
return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
}
/**
* Define a one-to-one relationship.
*
* @param string $related
* @param string $foreignKey
* @param string $localKey
*
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function hasOne($related, $foreignKey = null, $localKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related();
$localKey = $localKey ?: $this->getKeyName();
return new HasOne($instance->newQuery(), $this, $foreignKey, $localKey);
}
/**
* Define a one-to-many relationship.
*
* @param string $related
* @param string $foreignKey
* @param string $localKey
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function hasMany($related, $foreignKey = null, $localKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related();
$localKey = $localKey ?: $this->getKeyName();
return new HasMany($instance->newQuery(), $this, $foreignKey, $localKey);
}
/**
* Determine if the new and old values for a given key are numerically equivalent.
*
* @param string $key
*
* @return bool
*/
protected function originalIsNumericallyEquivalent($key)
{
$current = $this->attributes[$key];
$original = $this->original[$key];
// Date comparison.
if (in_array($key, $this->getDates())) {
$current = $current instanceof DateTime ? $this->asDateTime($current) : $current;
$original = $original instanceof DateTime ? $this->asDateTime($original) : $original;
return $current == $original;
}
return parent::originalIsNumericallyEquivalent($key);
}
}