diff --git a/README.md b/README.md
index 60c5fa5..89a89c7 100644
--- a/README.md
+++ b/README.md
@@ -300,7 +300,7 @@ $user->save(array(), array(), array(),
 
 Have you ever written an Eloquent model with a bunch of relations, just to notice how cluttered your class is, with all those one-liners that have almost the same content as the method name itself?
 
-In Ardent you can cleanly define your relationships in an array with their information, and they will work just like if you had defined they in methods. Here's an example:
+In Ardent you can cleanly define your relationships in an array with their information, and they will work just as if you had defined them as methods. Here's an example:
 
 ```php
 class User extends \LaravelBook\Ardent\Ardent {
@@ -315,22 +315,45 @@ $user = User::find($id);
 echo "{$user->address->street}, {$user->address->city} - {$user->address->state}";
 ```
 
-The array syntax is as follows:
+The array syntax should follow the form of 1 to 3 unnamed (numeric) index values followed by optional (and sometimes required) named index values. See the following for complete description:
 
-- First indexed value: relation name, being one of
+**First index value**
+
+This value should be the relation name, being one of
 [`hasOne`](http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_hasOne),
 [`hasMany`](http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_hasMany),
+[`hasManyThrough`](http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_hasManyThrough),
 [`belongsTo`](http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_belongsTo),
 [`belongsToMany`](http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_belongsToMany),
 [`morphTo`](http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_morphTo),
 [`morphOne`](http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_morphOne),
 [`morphMany`](http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_morphMany),
-or one of the related constants (`Ardent::HAS_MANY` or `Ardent::MORPH_ONE` for example).
-- Second indexed: class name, with complete namespace. The exception is `morphTo` relations, that take no additional argument.
-- named arguments, following the ones defined for the original Eloquent methods:
-    - `foreignKey` [optional], valid for `hasOne`, `hasMany`, `belongsTo` and `belongsToMany`
-    - `table`,`otherKey` [optional],`timestamps` [boolean, optional], and `pivotKeys` [array, optional], valid for `belongsToMany`
-    - `name`, `type` and `id`, used by `morphTo`, `morphOne` and `morphMany` (the last two requires `name` to be defined)
+or one of the related constants (`Ardent::HAS_MANY`, `Ardent::MORPH_ONE`, etc.).
+
+**Second index value**
+
+This value should be the related model class name, _with complete namespace_. The `morphTo` relationship does not require a second indexed value and will throw an exception if provided.
+
+**Third index value**
+
+This value should be the related "through" model class name, _with complete namespace_. This index is only required by the `hasManyThrough` relationship type.
+
+**Named indexes**
+
+Following the first, second, and third numeric indexes are named index values from the original Eloquent methods:
+
+- `foreignKey`: optional for `hasOne`, `hasMany`, `belongsTo`, `belongsToMany`
+- `firstKey`: optional for `hasManyThrough`
+- `secondKey`: optional for `hasManyThrough`
+- `otherKey`: optional for `belongsTo`, `belongsToMany`
+- `localKey`: optional for `hasOne`, `hasMany`, `morphOne`, `morphMany`
+- `table`: optional for `belongsToMany`
+- `timestamps`: optional for `belongsToMany`
+- `pivotKeys`: optional for `belongsToMany`
+- `relation`: optional for `belongsTo` and `belongsToMany`
+- `name`: optional for `morphTo` and required for `morphOne`, `morphMany`
+- `type`: optional for `morphTo`, `morphOne`, `morphMany`
+- `id`: optional for `morphTo`, `morphOne`, `morphMany`
     
 > **Note:** This feature was based on the easy [relations on Yii 1.1 ActiveRecord](http://www.yiiframework.com/doc/guide/1.1/en/database.arr#declaring-relationship).
 
diff --git a/composer.json b/composer.json
index 2cdc960..226f3e6 100644
--- a/composer.json
+++ b/composer.json
@@ -24,10 +24,10 @@
         "email": "contact@laravelbook.com"
     },
     "require": {
-        "php": ">=5.3.0",
-        "illuminate/support": "~4.1",
-        "illuminate/database": "~4.1",
-        "illuminate/validation": "~4.1"
+        "php": ">=5.4.0",
+        "illuminate/support": "~4.2",
+        "illuminate/database": "~4.2",
+        "illuminate/validation": "~4.2"
     },
     "autoload": {
         "psr-0": {
diff --git a/src/LaravelBook/Ardent/Ardent.php b/src/LaravelBook/Ardent/Ardent.php
index 49386fd..e2d89dc 100755
--- a/src/LaravelBook/Ardent/Ardent.php
+++ b/src/LaravelBook/Ardent/Ardent.php
@@ -31,206 +31,209 @@
  */
 abstract class Ardent extends Model {
 
-    /**
-     * The rules to be applied to the data.
-     *
-     * @var array
-     */
-    public static $rules = array();
-
-    /**
-     * The array of custom error messages.
-     *
-     * @var array
-     */
-    public static $customMessages = array();
-
-    /**
-     * The message bag instance containing validation error messages
-     *
-     * @var \Illuminate\Support\MessageBag
-     */
-    public $validationErrors;
-
-    /**
-     * Makes the validation procedure throw an {@link InvalidModelException} instead of returning
-     * false when validation fails.
-     *
-     * @var bool
-     */
-    public $throwOnValidation = false;
-
-    /**
-     * Forces the behavior of findOrFail in very find method - throwing a {@link ModelNotFoundException}
-     * when the model is not found.
-     *
-     * @var bool
-     */
-    public static $throwOnFind = false;
-
-    /**
-     * If set to true, the object will automatically populate model attributes from Input::all()
-     *
-     * @var bool
-     */
-    public $autoHydrateEntityFromInput = false;
-
-    /**
-     * By default, Ardent will attempt hydration only if the model object contains no attributes and
-     * the $autoHydrateEntityFromInput property is set to true.
-     * Setting $forceEntityHydrationFromInput to true will bypass the above check and enforce
-     * hydration of model attributes.
-     *
-     * @var bool
-     */
-    public $forceEntityHydrationFromInput = false;
-
-    /**
-     * If set to true, the object will automatically remove redundant model
-     * attributes (i.e. confirmation fields).
-     *
-     * @var bool
-     */
-    public $autoPurgeRedundantAttributes = false;
-
-    /**
-     * Array of closure functions which determine if a given attribute is deemed
-     * redundant (and should not be persisted in the database)
-     *
-     * @var array
-     */
-    protected $purgeFilters = array();
-
-    protected $purgeFiltersInitialized = false;
-
-    /**
-     * List of attribute names which should be hashed using the Bcrypt hashing algorithm.
-     *
-     * @var array
-     */
-    public static $passwordAttributes = array();
-
-    /**
-     * If set to true, the model will automatically replace all plain-text passwords
-     * attributes (listed in $passwordAttributes) with hash checksums
-     *
-     * @var bool
-     */
-    public $autoHashPasswordAttributes = false;
-
-    /**
-     * If set to true will try to instantiate the validator as if it was outside Laravel.
-     *
-     * @var bool
-     */
-    protected static $externalValidator = false;
-
-    /**
-     * A Translator instance, to be used by standalone Ardent instances.
-     *
-     * @var \Illuminate\Validation\Factory
-     */
-    protected static $validationFactory;
-
-    /**
-     * Can be used to ease declaration of relationships in Ardent models.
-     * Follows closely the behavior of the relation methods used by Eloquent, but packing them into an indexed array
-     * with relation constants make the code less cluttered.
-     *
-     * It should be declared with camel-cased keys as the relation name, and value being a mixed array with the
-     * relation constant being the first (0) value, the second (1) being the classname and the next ones (optionals)
-     * having named keys indicating the other arguments of the original methods: 'foreignKey' (belongsTo, hasOne,
-     * belongsToMany and hasMany); 'table' and 'otherKey' (belongsToMany only); 'name', 'type' and 'id' (specific for
-     * morphTo, morphOne and morphMany).
-     * Exceptionally, the relation type MORPH_TO does not include a classname, following the method declaration of
-     * {@link \Illuminate\Database\Eloquent\Model::morphTo}.
-     *
-     * Example:
-     * 
-     * class Order extends Ardent {
-     *     protected static $relations = array(
-     *         'items'    => array(self::HAS_MANY, 'Item'),
-     *         'owner'    => array(self::HAS_ONE, 'User', 'foreignKey' => 'user_id'),
-     *         'pictures' => array(self::MORPH_MANY, 'Picture', 'name' => 'imageable')
-     *     );
-     * }
-     * 
-     *
-     * @see \Illuminate\Database\Eloquent\Model::hasOne
-     * @see \Illuminate\Database\Eloquent\Model::hasMany
-     * @see \Illuminate\Database\Eloquent\Model::belongsTo
-     * @see \Illuminate\Database\Eloquent\Model::belongsToMany
-     * @see \Illuminate\Database\Eloquent\Model::morphTo
-     * @see \Illuminate\Database\Eloquent\Model::morphOne
-     * @see \Illuminate\Database\Eloquent\Model::morphMany
-     *
-     * @var array
-     */
-    protected static $relationsData = array();
-
-    const HAS_ONE = 'hasOne';
-
-    const HAS_MANY = 'hasMany';
-
-    const BELONGS_TO = 'belongsTo';
-
-    const BELONGS_TO_MANY = 'belongsToMany';
-
-    const MORPH_TO = 'morphTo';
-
-    const MORPH_ONE = 'morphOne';
-
-    const MORPH_MANY = 'morphMany';
-
-    /**
-     * Array of relations used to verify arguments used in the {@link $relationsData}
-     *
-     * @var array
-     */
-    protected static $relationTypes = array(
-        self::HAS_ONE, self::HAS_MANY,
-        self::BELONGS_TO, self::BELONGS_TO_MANY,
-        self::MORPH_TO, self::MORPH_ONE, self::MORPH_MANY
-    );
-
-    /**
-     * Create a new Ardent model instance.
-     *
-     * @param array $attributes
-     * @return \LaravelBook\Ardent\Ardent
-     */
-    public function __construct(array $attributes = array()) {
-
-        parent::__construct($attributes);
-        $this->validationErrors = new MessageBag;
-    }
-
-    /**
-     * The "booting" method of the model.
-     * Overrided to attach before/after method hooks into the model events.
-     *
-     * @see \Illuminate\Database\Eloquent\Model::boot()
-     * @return void
-     */
-    public static function boot() {
-        parent::boot();
-
-        $myself   = get_called_class();
-        $hooks    = array('before' => 'ing', 'after' => 'ed');
-        $radicals = array('sav', 'validat', 'creat', 'updat', 'delet');
-
-        foreach ($radicals as $rad) {
-            foreach ($hooks as $hook => $event) {
-                $method = $hook.ucfirst($rad).'e';
-                if (method_exists($myself, $method)) {
-                    $eventMethod = $rad.$event;
-                    self::$eventMethod(function($model) use ($method){
-                        return $model->$method($model);
-                    });
-                }
-            }
-        }
-    }
+	/**
+	 * The rules to be applied to the data.
+	 *
+	 * @var array
+	 */
+	public static $rules = array();
+
+	/**
+	 * The array of custom error messages.
+	 *
+	 * @var array
+	 */
+	public static $customMessages = array();
+
+	/**
+	 * The message bag instance containing validation error messages
+	 *
+	 * @var \Illuminate\Support\MessageBag
+	 */
+	public $validationErrors;
+
+	/**
+	 * Makes the validation procedure throw an {@link InvalidModelException} instead of returning
+	 * false when validation fails.
+	 *
+	 * @var bool
+	 */
+	public $throwOnValidation = false;
+
+	/**
+	 * Forces the behavior of findOrFail in very find method - throwing a {@link ModelNotFoundException}
+	 * when the model is not found.
+	 *
+	 * @var bool
+	 */
+	public static $throwOnFind = false;
+
+	/**
+	 * If set to true, the object will automatically populate model attributes from Input::all()
+	 *
+	 * @var bool
+	 */
+	public $autoHydrateEntityFromInput = false;
+
+	/**
+	 * By default, Ardent will attempt hydration only if the model object contains no attributes and
+	 * the $autoHydrateEntityFromInput property is set to true.
+	 * Setting $forceEntityHydrationFromInput to true will bypass the above check and enforce
+	 * hydration of model attributes.
+	 *
+	 * @var bool
+	 */
+	public $forceEntityHydrationFromInput = false;
+
+	/**
+	 * If set to true, the object will automatically remove redundant model
+	 * attributes (i.e. confirmation fields).
+	 *
+	 * @var bool
+	 */
+	public $autoPurgeRedundantAttributes = false;
+
+	/**
+	 * Array of closure functions which determine if a given attribute is deemed
+	 * redundant (and should not be persisted in the database)
+	 *
+	 * @var array
+	 */
+	protected $purgeFilters = array();
+
+	protected $purgeFiltersInitialized = false;
+
+	/**
+	 * List of attribute names which should be hashed using the Bcrypt hashing algorithm.
+	 *
+	 * @var array
+	 */
+	public static $passwordAttributes = array();
+
+	/**
+	 * If set to true, the model will automatically replace all plain-text passwords
+	 * attributes (listed in $passwordAttributes) with hash checksums
+	 *
+	 * @var bool
+	 */
+	public $autoHashPasswordAttributes = false;
+
+	/**
+	 * If set to true will try to instantiate the validator as if it was outside Laravel.
+	 *
+	 * @var bool
+	 */
+	protected static $externalValidator = false;
+
+	/**
+	 * A Translator instance, to be used by standalone Ardent instances.
+	 *
+	 * @var \Illuminate\Validation\Factory
+	 */
+	protected static $validationFactory;
+
+	/**
+	 * Can be used to ease declaration of relationships in Ardent models.
+	 * Follows closely the behavior of the relation methods used by Eloquent, but packing them into an indexed array
+	 * with relation constants make the code less cluttered.
+	 *
+	 * It should be declared with camel-cased keys as the relation name, and value being a mixed array with the
+	 * relation constant being the first (0) value, the second (1) being the classname and the next ones (optionals)
+	 * having named keys indicating the other arguments of the original methods: 'foreignKey' (belongsTo, hasOne,
+	 * belongsToMany and hasMany); 'table' and 'otherKey' (belongsToMany only); 'name', 'type' and 'id' (specific for
+	 * morphTo, morphOne and morphMany).
+	 * Exceptionally, the relation type MORPH_TO does not include a classname, following the method declaration of
+	 * {@link \Illuminate\Database\Eloquent\Model::morphTo}.
+	 *
+	 * Example:
+	 * 
+	 * class Order extends Ardent {
+	 *     protected static $relations = array(
+	 *         'items'    => array(self::HAS_MANY, 'Item'),
+	 *         'owner'    => array(self::HAS_ONE, 'User', 'foreignKey' => 'user_id'),
+	 *         'pictures' => array(self::MORPH_MANY, 'Picture', 'name' => 'imageable')
+	 *     );
+	 * }
+	 * 
+	 *
+	 * @see \Illuminate\Database\Eloquent\Model::hasOne
+	 * @see \Illuminate\Database\Eloquent\Model::hasMany
+	 * @see \Illuminate\Database\Eloquent\Model::hasManyThrough
+	 * @see \Illuminate\Database\Eloquent\Model::belongsTo
+	 * @see \Illuminate\Database\Eloquent\Model::belongsToMany
+	 * @see \Illuminate\Database\Eloquent\Model::morphTo
+	 * @see \Illuminate\Database\Eloquent\Model::morphOne
+	 * @see \Illuminate\Database\Eloquent\Model::morphMany
+	 *
+	 * @var array
+	 */
+	protected static $relationsData = array();
+
+	const HAS_ONE = 'hasOne';
+
+	const HAS_MANY = 'hasMany';
+
+	const HAS_MANY_THROUGH = 'hasManyThrough';
+
+	const BELONGS_TO = 'belongsTo';
+
+	const BELONGS_TO_MANY = 'belongsToMany';
+
+	const MORPH_TO = 'morphTo';
+
+	const MORPH_ONE = 'morphOne';
+
+	const MORPH_MANY = 'morphMany';
+
+	/**
+	 * Array of relations used to verify arguments used in the {@link $relationsData}
+	 *
+	 * @var array
+	 */
+	protected static $relationTypes = array(
+		self::HAS_ONE, self::HAS_MANY, self::HAS_MANY_THROUGH,
+		self::BELONGS_TO, self::BELONGS_TO_MANY,
+		self::MORPH_TO, self::MORPH_ONE, self::MORPH_MANY
+	);
+
+	/**
+	 * Create a new Ardent model instance.
+	 *
+	 * @param array $attributes
+	 * @return \LaravelBook\Ardent\Ardent
+	 */
+	public function __construct(array $attributes = array()) {
+
+		parent::__construct($attributes);
+		$this->validationErrors = new MessageBag;
+	}
+
+	/**
+	 * The "booting" method of the model.
+	 * Overrided to attach before/after method hooks into the model events.
+	 *
+	 * @see \Illuminate\Database\Eloquent\Model::boot()
+	 * @return void
+	 */
+	public static function boot() {
+		parent::boot();
+
+		$myself   = get_called_class();
+		$hooks    = array('before' => 'ing', 'after' => 'ed');
+		$radicals = array('sav', 'validat', 'creat', 'updat', 'delet');
+
+		foreach ($radicals as $rad) {
+			foreach ($hooks as $hook => $event) {
+				$method = $hook.ucfirst($rad).'e';
+				if (method_exists($myself, $method)) {
+					$eventMethod = $rad.$event;
+					self::$eventMethod(function($model) use ($method){
+						return $model->$method($model);
+					});
+				}
+			}
+		}
+	}
 
 	public function getObservableEvents() {
 		return array_merge(
@@ -259,132 +262,153 @@ public static function validated($callback) {
 		static::registerModelEvent('validated', $callback);
 	}
 
-    /**
-     * Looks for the relation in the {@link $relationsData} array and does the correct magic as Eloquent would require
-     * inside relation methods. For more information, read the documentation of the mentioned property.
-     *
-     * @param string $relationName the relation key, camel-case version
-     * @return \Illuminate\Database\Eloquent\Relations\Relation
-     * @throws \InvalidArgumentException when the first param of the relation is not a relation type constant,
-     *      or there's one or more arguments missing
-     * @see Ardent::relationsData
-     */
-    protected function handleRelationalArray($relationName) {
-        $relation     = static::$relationsData[$relationName];
-        $relationType = $relation[0];
-        $errorHeader  = "Relation '$relationName' on model '".get_called_class();
-
-        if (!in_array($relationType, static::$relationTypes)) {
-            throw new \InvalidArgumentException($errorHeader.
-            ' should have as first param one of the relation constants of the Ardent class.');
-        }
-        if (!isset($relation[1]) && $relationType != self::MORPH_TO) {
-            throw new \InvalidArgumentException($errorHeader.
-            ' should have at least two params: relation type and classname.');
-        }
-        if (isset($relation[1]) && $relationType == self::MORPH_TO) {
-            throw new \InvalidArgumentException($errorHeader.
-            ' is a morphTo relation and should not contain additional arguments.');
-        }
-
-        $verifyArgs = function (array $opt, array $req = array()) use ($relationName, &$relation, $errorHeader) {
-            $missing = array('req' => array(), 'opt' => array());
-
-            foreach (array('req', 'opt') as $keyType) {
-                foreach ($$keyType as $key) {
-                    if (!array_key_exists($key, $relation)) {
-                        $missing[$keyType][] = $key;
-                    }
-                }
-            }
-
-            if ($missing['req']) {
-                throw new \InvalidArgumentException($errorHeader.'
-                    should contain the following key(s): '.join(', ', $missing['req']));
-            }
-            if ($missing['opt']) {
-                foreach ($missing['opt'] as $include) {
-                    $relation[$include] = null;
-                }
-            }
-        };
-
-        switch ($relationType) {
-            case self::HAS_ONE:
-            case self::HAS_MANY:
-            case self::BELONGS_TO:
-                $verifyArgs(array('foreignKey'));
-                return $this->$relationType($relation[1], $relation['foreignKey']);
-
-            case self::BELONGS_TO_MANY:
-                $verifyArgs(array('table', 'foreignKey', 'otherKey'));
-                $relationship = $this->$relationType($relation[1], $relation['table'], $relation['foreignKey'], $relation['otherKey']);
-                if(isset($relation['pivotKeys']) && is_array($relation['pivotKeys']))
-                    $relationship->withPivot($relation['pivotKeys']);
-                if(isset($relation['timestamps']) && $relation['timestamps']==true)
-                    $relationship->withTimestamps();
-                return $relationship;
-
-            case self::MORPH_TO:
-                $verifyArgs(array('name', 'type', 'id'));
-                return $this->$relationType($relation['name'], $relation['type'], $relation['id']);
-
-            case self::MORPH_ONE:
-            case self::MORPH_MANY:
-                $verifyArgs(array('type', 'id'), array('name'));
-                return $this->$relationType($relation[1], $relation['name'], $relation['type'], $relation['id']);
-        }
-    }
-
-    /**
-     * Handle dynamic method calls into the method.
-     * Overrided from {@link Eloquent} to implement recognition of the {@link $relationsData} array.
-     *
-     * @param  string $method
-     * @param  array  $parameters
-     * @return mixed
-     */
-    public function __call($method, $parameters) {
-        if (array_key_exists($method, static::$relationsData)) {
-            return $this->handleRelationalArray($method);
-        }
-
-        return parent::__call($method, $parameters);
-    }
+	/**
+	 * Looks for the relation in the {@link $relationsData} array and does the correct magic as Eloquent would require
+	 * inside relation methods. For more information, read the documentation of the mentioned property.
+	 *
+	 * @param string $relationName the relation key, camel-case version
+	 * @return \Illuminate\Database\Eloquent\Relations\Relation
+	 * @throws \InvalidArgumentException when the first param of the relation is not a relation type constant,
+	 *      or there's one or more arguments missing
+	 * @see Ardent::relationsData
+	 */
+	protected function handleRelationalArray($relationName) {
+		$relation     = static::$relationsData[$relationName];
+		$relationType = $relation[0];
+		$errorHeader  = "Relation '$relationName' on model '".get_called_class();
+
+		if (!in_array($relationType, static::$relationTypes)) {
+			throw new \InvalidArgumentException($errorHeader.
+			' should have as first parameter one of the relation constants of the Ardent class.');
+		}
+		if (!isset($relation[1]) && $relationType != self::MORPH_TO) {
+			throw new \InvalidArgumentException($errorHeader.
+			' should have at least two parameters: relation type and classname.');
+		}
+		if (isset($relation[1]) && $relationType == self::MORPH_TO) {
+			throw new \InvalidArgumentException($errorHeader.
+			' is a morphTo relation and should not contain additional arguments.');
+		}
+		if (isset($relation[2]) && $relationType != self::HAS_MANY_THROUGH) {
+			throw new \InvalidArgumentException($errorHeader.
+			' is not a hasManyThrough relation and should not contain additional arguments.');
+		}
+		if (!isset($relation[2]) && $relationType == self::HAS_MANY_THROUGH) {
+			throw new \InvalidArgumentException($errorHeader.
+			' is a hasManyThrough relation and should have atleast three parameters: relation type, related model classname and through model classname.');
+		}
+
+		$verifyArgs = function (array $opt, array $req = array()) use ($relationName, &$relation, $errorHeader) {
+			$missing = array('req' => array(), 'opt' => array());
+
+			foreach (array('req', 'opt') as $keyType) {
+				foreach ($$keyType as $key) {
+					if (!array_key_exists($key, $relation)) {
+						$missing[$keyType][] = $key;
+					}
+				}
+			}
+
+			if ($missing['req']) {
+				throw new \InvalidArgumentException($errorHeader.'
+					should contain the following key(s): '.join(', ', $missing['req']));
+			}
+			if ($missing['opt']) {
+				foreach ($missing['opt'] as $include) {
+					$relation[$include] = null;
+				}
+			}
+		};
+
+		switch ($relationType) {
+			case self::HAS_ONE:
+			case self::HAS_MANY:
+				$verifyArgs(array('foreignKey', 'localKey'));
+				return $this->$relationType($relation[1], $relation['foreignKey'], $relation['localKey']);
+
+			case self::HAS_MANY_THROUGH:
+				$verifyArgs(array('firstKey', 'secondKey'));
+				return $this->$relationType($relation[1], $relation[2], $relation['firstKey'], $relation['secondKey']);
+
+			case self::BELONGS_TO:
+				$verifyArgs(array('foreignKey', 'otherKey', 'relation'));
+				return $this->$relationType($relation[1], $relation['foreignKey'], $relation['otherKey'], $relation['relation']);
+
+			case self::BELONGS_TO_MANY:
+				$verifyArgs(array('table', 'foreignKey', 'otherKey', 'relation', 'pivotKeys', 'timestamps'));
+				$relationship = $this->$relationType($relation[1], $relation['table'], $relation['foreignKey'], $relation['otherKey'], $relation['relation']);
+				if(isset($relation['pivotKeys']) && is_array($relation['pivotKeys'])) {
+					$relationship->withPivot($relation['pivotKeys']);
+				}
+				if(isset($relation['timestamps']) && $relation['timestamps']===true) {
+					$relationship->withTimestamps();
+				}
+				return $relationship;
+
+			case self::MORPH_TO:
+				$verifyArgs(array('name', 'type', 'id'));
+				return $this->$relationType($relation['name'], $relation['type'], $relation['id']);
+
+			case self::MORPH_ONE:
+			case self::MORPH_MANY:
+				$verifyArgs(array('type', 'id', 'localKey'), array('name'));
+				return $this->$relationType($relation[1], $relation['name'], $relation['type'], $relation['id'], $relation['localKey']);
+		}
+	}
+
+	/**
+	 * Handle dynamic method calls into the method.
+	 * Overrided from {@link Eloquent} to implement recognition of the {@link $relationsData} array.
+	 *
+	 * @param  string $method
+	 * @param  array  $parameters
+	 * @return mixed
+	 */
+	public function __call($method, $parameters) {
+		if (array_key_exists($method, static::$relationsData)) {
+			return $this->handleRelationalArray($method);
+		}
+
+		return parent::__call($method, $parameters);
+	}
 
 
 	/**
 	 * Define an inverse one-to-one or many relationship.
-	 * Overriden from {@link Eloquent\Model} to allow the usage of the intermediary methods to handle the {@link
-	 * $relationsData} array.
+	 * Overriden from {@link Eloquent\Model} to allow the usage
+	 * of the intermediary methods to handle the {@link $relationsData} array.
 	 *
 	 * @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 relatinoships.
 		$backtrace = debug_backtrace(false);
 		$caller = ($backtrace[1]['function'] == 'handleRelationalArray')? $backtrace[3] : $backtrace[1];
+		$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.
-		$relation = $caller['function'];
-
 		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.
-		$instance = new $related;
-		
-		$otherKey = $otherKey ?: $instance->getKeyName();
-		
+		// actually be responsible for retrieving and hydrating every relations.		
 		$query = $instance->newQuery();
 
+		$otherKey = $otherKey ?: $instance->getKeyName();
+
 		return new BelongsTo($query, $this, $foreignKey, $otherKey, $relation);
 	}
 
@@ -420,102 +444,102 @@ public function morphTo($name = null, $type = null, $id = null) {
 		return $this->belongsTo($class, $id);
 	}
 
-    /**
-     * Get an attribute from the model.
-     * Overrided from {@link Eloquent} to implement recognition of the {@link $relationsData} array.
-     *
-     * @param  string $key
-     * @return mixed
-     */
-    public function getAttribute($key) {
-        $attr = parent::getAttribute($key);
-
-        if ($attr === null) {
-            $camelKey = camel_case($key);
-            if (array_key_exists($camelKey, static::$relationsData)) {
-                $this->relations[$key] = $this->$camelKey()->getResults();
-                return $this->relations[$key];
-            }
-        }
-
-        return $attr;
-    }
-
-    /**
-     * Configures Ardent to be used outside of Laravel - correctly setting Eloquent and Validation modules.
-     * @todo Should allow for additional language files. Would probably receive a Translator instance as an optional argument, or a list of translation files.
-     *
-     * @param array $connection Connection info used by {@link \Illuminate\Database\Capsule\Manager::addConnection}.
-     * Should contain driver, host, port, database, username, password, charset and collation.
-     */
-    public static function configureAsExternal(array $connection) {
-        $db = new DatabaseCapsule;
-        $db->addConnection($connection);
-        $db->setEventDispatcher(new Dispatcher(new Container));
-        //TODO: configure a cache manager (as an option)
-
-        // Make this Capsule instance available globally via static methods
-        $db->setAsGlobal();
-        
-        $db->bootEloquent();
-
-        $translator = new Translator('en');
-        $translator->addLoader('file_loader', new PhpFileLoader());
-        $translator->addResource('file_loader',
-            dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'lang'.DIRECTORY_SEPARATOR.'en'.
-            DIRECTORY_SEPARATOR.'validation.php', 'en');
-
-        self::$externalValidator = true;
-        self::$validationFactory = new ValidationFactory($translator);
-        self::$validationFactory->setPresenceVerifier(new DatabasePresenceVerifier($db->getDatabaseManager()));
-    }
-
-    /**
-     * Instatiates the validator used by the validation process, depending if the class is being used inside or
-     * outside of Laravel.
-     *
-     * @param $data
-     * @param $rules
-     * @param $customMessages
-     * @return \Illuminate\Validation\Validator
-     * @see Ardent::$externalValidator
-     */
-    protected static function makeValidator($data, $rules, $customMessages) {
-        if (self::$externalValidator) {
-            return self::$validationFactory->make($data, $rules, $customMessages);
-        } else {
-            return Validator::make($data, $rules, $customMessages);
-        }
-    }
-
-    /**
-     * Validate the model instance
-     *
-     * @param array $rules          Validation rules
-     * @param array $customMessages Custom error messages
-     * @return bool
-     * @throws InvalidModelException
-     */
-    public function validate(array $rules = array(), array $customMessages = array()) {
-        if ($this->fireModelEvent('validating') === false) {
-            if ($this->throwOnValidation) {
-                throw new InvalidModelException($this);
-            } else {
-                return false;
-            }
-        }
-
-        // check for overrides, then remove any empty rules
-        $rules = (empty($rules))? static::$rules : $rules;
-        foreach ($rules as $field => $rls) {
-            if ($rls == '') {
-                unset($rules[$field]);
-            }
-        }
-
-        if (empty($rules)) {
-            $success = true;
-        } else {
+	/**
+	 * Get an attribute from the model.
+	 * Overrided from {@link Eloquent} to implement recognition of the {@link $relationsData} array.
+	 *
+	 * @param  string $key
+	 * @return mixed
+	 */
+	public function getAttribute($key) {
+		$attr = parent::getAttribute($key);
+
+		if ($attr === null) {
+			$camelKey = camel_case($key);
+			if (array_key_exists($camelKey, static::$relationsData)) {
+				$this->relations[$key] = $this->$camelKey()->getResults();
+				return $this->relations[$key];
+			}
+		}
+
+		return $attr;
+	}
+
+	/**
+	 * Configures Ardent to be used outside of Laravel - correctly setting Eloquent and Validation modules.
+	 * @todo Should allow for additional language files. Would probably receive a Translator instance as an optional argument, or a list of translation files.
+	 *
+	 * @param array $connection Connection info used by {@link \Illuminate\Database\Capsule\Manager::addConnection}.
+	 * Should contain driver, host, port, database, username, password, charset and collation.
+	 */
+	public static function configureAsExternal(array $connection) {
+		$db = new DatabaseCapsule;
+		$db->addConnection($connection);
+		$db->setEventDispatcher(new Dispatcher(new Container));
+		//TODO: configure a cache manager (as an option)
+
+		// Make this Capsule instance available globally via static methods
+		$db->setAsGlobal();
+
+		$db->bootEloquent();
+
+		$translator = new Translator('en');
+		$translator->addLoader('file_loader', new PhpFileLoader());
+		$translator->addResource('file_loader',
+			dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'lang'.DIRECTORY_SEPARATOR.'en'.
+			DIRECTORY_SEPARATOR.'validation.php', 'en');
+
+		self::$externalValidator = true;
+		self::$validationFactory = new ValidationFactory($translator);
+		self::$validationFactory->setPresenceVerifier(new DatabasePresenceVerifier($db->getDatabaseManager()));
+	}
+
+	/**
+	 * Instatiates the validator used by the validation process, depending if the class is being used inside or
+	 * outside of Laravel.
+	 *
+	 * @param $data
+	 * @param $rules
+	 * @param $customMessages
+	 * @return \Illuminate\Validation\Validator
+	 * @see Ardent::$externalValidator
+	 */
+	protected static function makeValidator($data, $rules, $customMessages) {
+		if (self::$externalValidator) {
+			return self::$validationFactory->make($data, $rules, $customMessages);
+		} else {
+			return Validator::make($data, $rules, $customMessages);
+		}
+	}
+
+	/**
+	 * Validate the model instance
+	 *
+	 * @param array $rules          Validation rules
+	 * @param array $customMessages Custom error messages
+	 * @return bool
+	 * @throws InvalidModelException
+	 */
+	public function validate(array $rules = array(), array $customMessages = array()) {
+		if ($this->fireModelEvent('validating') === false) {
+			if ($this->throwOnValidation) {
+				throw new InvalidModelException($this);
+			} else {
+				return false;
+			}
+		}
+
+		// check for overrides, then remove any empty rules
+		$rules = (empty($rules))? static::$rules : $rules;
+		foreach ($rules as $field => $rls) {
+			if ($rls == '') {
+				unset($rules[$field]);
+			}
+		}
+
+		if (empty($rules)) {
+			$success = true;
+		} else {
 			$customMessages = (empty($customMessages))? static::$customMessages : $customMessages;
 
 			if ($this->forceEntityHydrationFromInput || (empty($this->attributes) && $this->autoHydrateEntityFromInput)) {
@@ -544,296 +568,295 @@ public function validate(array $rules = array(), array $customMessages = array()
 			}
 		}
 
-        $this->fireModelEvent('validated', false);
-
-	    if (!$success && $this->throwOnValidation) {
-		    throw new InvalidModelException($this);
-	    }
-
-        return $success;
-    }
-
-    /**
-     * Save the model to the database. Is used by {@link save()} and {@link forceSave()} as a way to DRY code.
-     *
-     * @param array   $rules
-     * @param array   $customMessages
-     * @param array   $options
-     * @param Closure $beforeSave
-     * @param Closure $afterSave
-     * @param bool    $force          Forces saving invalid data.
-
-     * @return bool
-     * @see Ardent::save()
-     * @see Ardent::forceSave()
-     */
-    protected function internalSave(array $rules = array(),
-        array $customMessages = array(),
-        array $options = array(),
-        Closure $beforeSave = null,
-        Closure $afterSave = null,
-        $force = false
-    ) {
-        if ($beforeSave) {
-            self::saving($beforeSave);
-        }
-        if ($afterSave) {
-            self::saved($afterSave);
-        }
-
-        $valid = $this->validate($rules, $customMessages);
-
-        if ($force || $valid) {
-            return $this->performSave($options);
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Save the model to the database.
-     *
-     * @param array   $rules
-     * @param array   $customMessages
-     * @param array   $options
-     * @param Closure $beforeSave
-     * @param Closure $afterSave
-     *
-     * @return bool
-     * @see Ardent::forceSave()
-     */
-    public function save(array $rules = array(),
-        array $customMessages = array(),
-        array $options = array(),
-        Closure $beforeSave = null,
-        Closure $afterSave = null
-    ) {
-        return $this->internalSave($rules, $customMessages, $options, $beforeSave, $afterSave, false);
-    }
-
-    /**
-     * Force save the model even if validation fails.
-     *
-     * @param array   $rules
-     * @param array   $customMessages
-     * @param array   $options
-     * @param Closure $beforeSave
-     * @param Closure $afterSave
-     * @return bool
-     * @see Ardent::save()
-     */
-    public function forceSave(array $rules = array(),
-        array $customMessages = array(),
-        array $options = array(),
-        Closure $beforeSave = null,
-        Closure $afterSave = null
-    ) {
-        return $this->internalSave($rules, $customMessages, $options, $beforeSave, $afterSave, true);
-    }
-
-
-    /**
-     * Add the basic purge filters
-     *
-     * @return void
-     */
-    protected function addBasicPurgeFilters() {
-        if ($this->purgeFiltersInitialized) {
-            return;
-        }
-
-        $this->purgeFilters[] = function ($attributeKey) {
-            // disallow password confirmation fields
-            if (Str::endsWith($attributeKey, '_confirmation')) {
-                return false;
-            }
-
-            // "_method" is used by Illuminate\Routing\Router to simulate custom HTTP verbs
-            if (strcmp($attributeKey, '_method') === 0) {
-                return false;
-            }
-
-            // "_token" is used by Illuminate\Html\FormBuilder to add CSRF protection
-            if (strcmp($attributeKey, '_token') === 0) {
-                return false;
-            }
-
-            return true;
-        };
-
-        $this->purgeFiltersInitialized = true;
-    }
-
-    /**
-     * Removes redundant attributes from model
-     *
-     * @param array $array Input array
-     * @return array
-     */
-    protected function purgeArray(array $array = array()) {
-
-        $result = array();
-        $keys   = array_keys($array);
-
-        $this->addBasicPurgeFilters();
-
-        if (!empty($keys) && !empty($this->purgeFilters)) {
-            foreach ($keys as $key) {
-                $allowed = true;
-
-                foreach ($this->purgeFilters as $filter) {
-                    $allowed = $filter($key);
-
-                    if (!$allowed) {
-                        break;
-                    }
-                }
-
-                if ($allowed) {
-                    $result[$key] = $array[$key];
-                }
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * Saves the model instance to database. If necessary, it will purge the model attributes
-     * of unnecessary fields. It will also replace plain-text password fields with their hashes.
-     *
-     * @param array $options
-     * @return bool
-     */
-    protected function performSave(array $options) {
-
-        if ($this->autoPurgeRedundantAttributes) {
-            $this->attributes = $this->purgeArray($this->getAttributes());
-        }
-
-        if ($this->autoHashPasswordAttributes) {
-            $this->attributes = $this->hashPasswordAttributes($this->getAttributes(), static::$passwordAttributes);
-        }
-
-        return parent::save($options);
-    }
-
-    /**
-     * Get validation error message collection for the Model
-     *
-     * @return \Illuminate\Support\MessageBag
-     */
-    public function errors() {
-        return $this->validationErrors;
-    }
-
-    /**
-     * Automatically replaces all plain-text password attributes (listed in $passwordAttributes)
-     * with hash checksum.
-     *
-     * @param array $attributes
-     * @param array $passwordAttributes
-     * @return array
-     */
-    protected function hashPasswordAttributes(array $attributes = array(), array $passwordAttributes = array()) {
-
-        if (empty($passwordAttributes) || empty($attributes)) {
-            return $attributes;
-        }
-
-        $result = array();
-        foreach ($attributes as $key => $value) {
-
-            if (in_array($key, $passwordAttributes) && !is_null($value)) {
-                if ($value != $this->getOriginal($key)) {
-                    $result[$key] = Hash::make($value);
-                }
-            } else {
-                $result[$key] = $value;
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * When given an ID and a Laravel validation rules array, this function
-     * appends the ID to the 'unique' rules given. The resulting array can
-     * then be fed to a Ardent save so that unchanged values
-     * don't flag a validation issue. Rules can be in either strings
-     * with pipes or arrays, but the returned rules are in arrays.
-     *
-     * @param int   $id
-     * @param array $rules
-     *
-     * @return array Rules with exclusions applied
-     */
-    protected function buildUniqueExclusionRules(array $rules = array()) {
-      
-        if (!count($rules))
-          $rules = static::$rules;
-
-        foreach ($rules as $field => &$ruleset) {
-            // If $ruleset is a pipe-separated string, switch it to array
-            $ruleset = (is_string($ruleset))? explode('|', $ruleset) : $ruleset;
-
-            foreach ($ruleset as &$rule) {
-              if (strpos($rule, 'unique') === 0) {
-                $params = explode(',', $rule);
-
-                $uniqueRules = array();
-                
-                // Append table name if needed
-                $table = explode(':', $params[0]);
-                if (count($table) == 1)
-                  $uniqueRules[1] = $this->table;
-                else
-                  $uniqueRules[1] = $table[1];
-               
-                // Append field name if needed
-                if (count($params) == 1)
-                  $uniqueRules[2] = $field;
-                else
-                  $uniqueRules[2] = $params[1];
-
-                if (isset($this->primaryKey)) {
-                  $uniqueRules[3] = $this->{$this->primaryKey};
-                  $uniqueRules[4] = $this->primaryKey;
-                }
-                else {
-                  $uniqueRules[3] = $this->id;
-                }
-       
-                $rule = 'unique:' . implode(',', $uniqueRules);  
-              } // end if strpos unique
-              
-            } // end foreach ruleset
-        }
-        
-        return $rules;
-    }
-
-    /**
-     * Update a model, but filter uniques first to ensure a unique validation rule
-     * does not fire
-     *
-     * @param array   $rules
-     * @param array   $customMessages
-     * @param array   $options
-     * @param Closure $beforeSave
-     * @param Closure $afterSave
-     * @return bool
-     */
-    public function updateUniques(array $rules = array(),
-        array $customMessages = array(),
-        array $options = array(),
-        Closure $beforeSave = null,
-        Closure $afterSave = null
-    ) {
-        $rules = $this->buildUniqueExclusionRules($rules);
-        
-        return $this->save($rules, $customMessages, $options, $beforeSave, $afterSave);
-    }
+		$this->fireModelEvent('validated', false);
+
+		if (!$success && $this->throwOnValidation) {
+			throw new InvalidModelException($this);
+		}
+
+		return $success;
+	}
+
+	/**
+	 * Save the model to the database. Is used by {@link save()} and {@link forceSave()} as a way to DRY code.
+	 *
+	 * @param array   $rules
+	 * @param array   $customMessages
+	 * @param array   $options
+	 * @param Closure $beforeSave
+	 * @param Closure $afterSave
+	 * @param bool    $force          Forces saving invalid data.
+	 *
+	 * @return bool
+	 * @see Ardent::save()
+	 * @see Ardent::forceSave()
+	 */
+	protected function internalSave(array $rules = array(),
+		array $customMessages = array(),
+		array $options = array(),
+		Closure $beforeSave = null,
+		Closure $afterSave = null,
+		$force = false
+	) {
+		if ($beforeSave) {
+			self::saving($beforeSave);
+		}
+		if ($afterSave) {
+			self::saved($afterSave);
+		}
+
+		$valid = $this->validate($rules, $customMessages);
+
+		if ($force || $valid) {
+			return $this->performSave($options);
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * Save the model to the database.
+	 *
+	 * @param array   $rules
+	 * @param array   $customMessages
+	 * @param array   $options
+	 * @param Closure $beforeSave
+	 * @param Closure $afterSave
+	 *
+	 * @return bool
+	 * @see Ardent::forceSave()
+	 */
+	public function save(array $rules = array(),
+		array $customMessages = array(),
+		array $options = array(),
+		Closure $beforeSave = null,
+		Closure $afterSave = null
+	) {
+		return $this->internalSave($rules, $customMessages, $options, $beforeSave, $afterSave, false);
+	}
+
+	/**
+	 * Force save the model even if validation fails.
+	 *
+	 * @param array   $rules
+	 * @param array   $customMessages
+	 * @param array   $options
+	 * @param Closure $beforeSave
+	 * @param Closure $afterSave
+	 * @return bool
+	 * @see Ardent::save()
+	 */
+	public function forceSave(array $rules = array(),
+		array $customMessages = array(),
+		array $options = array(),
+		Closure $beforeSave = null,
+		Closure $afterSave = null
+	) {
+		return $this->internalSave($rules, $customMessages, $options, $beforeSave, $afterSave, true);
+	}
+
+	/**
+	 * Add the basic purge filters
+	 *
+	 * @return void
+	 */
+	protected function addBasicPurgeFilters() {
+		if ($this->purgeFiltersInitialized) {
+			return;
+		}
+
+		$this->purgeFilters[] = function ($attributeKey) {
+			// disallow password confirmation fields
+			if (Str::endsWith($attributeKey, '_confirmation')) {
+				return false;
+			}
+
+			// "_method" is used by Illuminate\Routing\Router to simulate custom HTTP verbs
+			if (strcmp($attributeKey, '_method') === 0) {
+				return false;
+			}
+
+			// "_token" is used by Illuminate\Html\FormBuilder to add CSRF protection
+			if (strcmp($attributeKey, '_token') === 0) {
+				return false;
+			}
+
+			return true;
+		};
+
+		$this->purgeFiltersInitialized = true;
+	}
+
+	/**
+	 * Removes redundant attributes from model
+	 *
+	 * @param array $array Input array
+	 * @return array
+	 */
+	protected function purgeArray(array $array = array()) {
+
+		$result = array();
+		$keys   = array_keys($array);
+
+		$this->addBasicPurgeFilters();
+
+		if (!empty($keys) && !empty($this->purgeFilters)) {
+			foreach ($keys as $key) {
+				$allowed = true;
+
+				foreach ($this->purgeFilters as $filter) {
+					$allowed = $filter($key);
+
+					if (!$allowed) {
+						break;
+					}
+				}
+
+				if ($allowed) {
+					$result[$key] = $array[$key];
+				}
+			}
+		}
+
+		return $result;
+	}
+
+	/**
+	 * Saves the model instance to database. If necessary, it will purge the model attributes
+	 * of unnecessary fields. It will also replace plain-text password fields with their hashes.
+	 *
+	 * @param array $options
+	 * @return bool
+	 */
+	protected function performSave(array $options) {
+
+		if ($this->autoPurgeRedundantAttributes) {
+			$this->attributes = $this->purgeArray($this->getAttributes());
+		}
+
+		if ($this->autoHashPasswordAttributes) {
+			$this->attributes = $this->hashPasswordAttributes($this->getAttributes(), static::$passwordAttributes);
+		}
+
+		return parent::save($options);
+	}
+
+	/**
+	 * Get validation error message collection for the Model
+	 *
+	 * @return \Illuminate\Support\MessageBag
+	 */
+	public function errors() {
+		return $this->validationErrors;
+	}
+
+	/**
+	 * Automatically replaces all plain-text password attributes (listed in $passwordAttributes)
+	 * with hash checksum.
+	 *
+	 * @param array $attributes
+	 * @param array $passwordAttributes
+	 * @return array
+	 */
+	protected function hashPasswordAttributes(array $attributes = array(), array $passwordAttributes = array()) {
+
+		if (empty($passwordAttributes) || empty($attributes)) {
+			return $attributes;
+		}
+
+		$result = array();
+		foreach ($attributes as $key => $value) {
+
+			if (in_array($key, $passwordAttributes) && !is_null($value)) {
+				if ($value != $this->getOriginal($key)) {
+					$result[$key] = Hash::make($value);
+				}
+			} else {
+				$result[$key] = $value;
+			}
+		}
+
+		return $result;
+	}
+
+	/**
+	 * When given an ID and a Laravel validation rules array, this function
+	 * appends the ID to the 'unique' rules given. The resulting array can
+	 * then be fed to a Ardent save so that unchanged values
+	 * don't flag a validation issue. Rules can be in either strings
+	 * with pipes or arrays, but the returned rules are in arrays.
+	 *
+	 * @param int   $id
+	 * @param array $rules
+	 *
+	 * @return array Rules with exclusions applied
+	 */
+	protected function buildUniqueExclusionRules(array $rules = array()) {
+
+		if (!count($rules))
+		  $rules = static::$rules;
+
+		foreach ($rules as $field => &$ruleset) {
+			// If $ruleset is a pipe-separated string, switch it to array
+			$ruleset = (is_string($ruleset))? explode('|', $ruleset) : $ruleset;
+
+			foreach ($ruleset as &$rule) {
+			  if (strpos($rule, 'unique') === 0) {
+				$params = explode(',', $rule);
+
+				$uniqueRules = array();
+
+				// Append table name if needed
+				$table = explode(':', $params[0]);
+				if (count($table) == 1)
+				  $uniqueRules[1] = $this->table;
+				else
+				  $uniqueRules[1] = $table[1];
+
+				// Append field name if needed
+				if (count($params) == 1)
+				  $uniqueRules[2] = $field;
+				else
+				  $uniqueRules[2] = $params[1];
+
+				if (isset($this->primaryKey)) {
+				  $uniqueRules[3] = $this->{$this->primaryKey};
+				  $uniqueRules[4] = $this->primaryKey;
+				}
+				else {
+				  $uniqueRules[3] = $this->id;
+				}
+
+				$rule = 'unique:' . implode(',', $uniqueRules);
+			  } // end if strpos unique
+
+			} // end foreach ruleset
+		}
+
+		return $rules;
+	}
+
+	/**
+	 * Update a model, but filter uniques first to ensure a unique validation rule
+	 * does not fire
+	 *
+	 * @param array   $rules
+	 * @param array   $customMessages
+	 * @param array   $options
+	 * @param Closure $beforeSave
+	 * @param Closure $afterSave
+	 * @return bool
+	 */
+	public function updateUniques(array $rules = array(),
+		array $customMessages = array(),
+		array $options = array(),
+		Closure $beforeSave = null,
+		Closure $afterSave = null
+	) {
+		$rules = $this->buildUniqueExclusionRules($rules);
+
+		return $this->save($rules, $customMessages, $options, $beforeSave, $afterSave);
+	}
 
 	/**
 	 * Validates a model with unique rules properly treated.
@@ -848,33 +871,34 @@ public function validateUniques(array $rules = array(), array $customMessages =
 		return $this->validate($rules, $customMessages);
 	}
 
-    /**
-     * Find a model by its primary key.
-     * If {@link $throwOnFind} is set, will use {@link findOrFail} internally.
-     *
-     * @param  mixed $id
-     * @param  array $columns
-     * @return Ardent|Collection
-     */
-    public static function find($id, $columns = array('*')) {
-        $debug = debug_backtrace(false);
-
-        if (static::$throwOnFind && $debug[1]['function'] != 'findOrFail') {
-            return self::findOrFail($id, $columns);
-        } else {
-            return parent::find($id, $columns);
-        }
-    }
+	/**
+	 * Find a model by its primary key.
+	 * If {@link $throwOnFind} is set, will use {@link findOrFail} internally.
+	 *
+	 * @param  mixed $id
+	 * @param  array $columns
+	 * @return Ardent|Collection
+	 */
+	public static function find($id, $columns = array('*')) {
+		$debug = debug_backtrace(false);
+
+		if (static::$throwOnFind && $debug[1]['function'] != 'findOrFail') {
+			return self::findOrFail($id, $columns);
+		} else {
+			return parent::find($id, $columns);
+		}
+	}
 
 	/**
 	 * Get a new query builder for the model's table.
 	 * Overriden from {@link \Model\Eloquent} to allow for usage of {@link throwOnFind}.
 	 *
-	 * @param  bool  $excludeDeleted
 	 * @return \Illuminate\Database\Eloquent\Builder
 	 */
-	public function newQuery($excludeDeleted = true) {
-		$builder = new Builder($this->newBaseQueryBuilder());
+	public function newQuery() {
+		$builder = $this->newEloquentBuilder(
+			$this->newBaseQueryBuilder()
+		);
 		$builder->throwOnFind = static::$throwOnFind;
 
 		// Once we have the query builders, we will set the model instances so the
@@ -882,11 +906,6 @@ public function newQuery($excludeDeleted = true) {
 		// while it is constructing and executing various queries against it.
 		$builder->setModel($this)->with($this->with);
 
-		if ($excludeDeleted and $this->softDelete)
-		{
-			$builder->whereNull($this->getQualifiedDeletedAtColumn());
-		}
-
-		return $builder;
+		return $this->applyGlobalScopes($builder);
 	}
 }