Commit 6254f616 authored by Jens Segers's avatar Jens Segers

Adding basic relations

parent a7ece360
......@@ -3,7 +3,7 @@ Laravel Eloquent MongoDB [![Build Status](https://travis-ci.org/jenssegers/Larav
An Eloquent model that supports MongoDB, inspired by LMongo, but using the original Eloquent methods.
*This model extends the original Eloquent model, so it uses exactly the same methods. Some advanced Eloquent features may not be working, but feel free to report them or issue a pull request!*
*This model extends the original Eloquent model, so it uses exactly the same methods.*
For more information about Eloquent, check http://laravel.com/docs/eloquent.
......@@ -189,6 +189,38 @@ You may also specify additional columns to update:
User::where('age', '29')->increment('age', 1, array('group' => 'thirty something'));
User::where('bmi', 30)->decrement('bmi', 1, array('category' => 'overweight'));
**Relations**
Support relations are:
- hasOne
- hasMany
- belongsTo
Example:
class User extends Eloquent {
public function items()
{
return $this->hasMany('Item');
}
}
And the inverse relation:
class Item extends Eloquent {
public function user()
{
return $this->belongsTo('User');
}
}
Other relations are not yet supported, but may be added in the future. Read more about these relations on http://four.laravel.com/docs/eloquent#relationships
**Raw Expressions**
These expressions will be injected directly into the query.
......
......@@ -64,7 +64,7 @@ class Builder extends \Illuminate\Database\Query\Builder {
if (is_null($this->columns)) $this->columns = $columns;
// Drop all columns if * is present
if (in_array('*', $this->columns))
if (in_array('*', $this->columns))
{
$this->columns = array();
}
......
<?php namespace Jenssegers\Mongodb;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Jenssegers\Mongodb\DatabaseManager as Resolver;
use Jenssegers\Mongodb\Builder as QueryBuilder;
use Jenssegers\Mongodb\Relations\BelongsTo;
use DateTime;
use MongoId;
......@@ -107,6 +111,69 @@ abstract class Model extends \Illuminate\Database\Eloquent\Model {
return parent::getTable();
}
/**
* Define a one-to-one relationship.
*
* @param string $related
* @param string $foreignKey
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function hasOne($related, $foreignKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related;
return new HasOne($instance->newQuery(), $this, $foreignKey);
}
/**
* Define a one-to-many relationship.
*
* @param string $related
* @param string $foreignKey
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function hasMany($related, $foreignKey = null)
{
$foreignKey = $foreignKey ?: $this->getForeignKey();
$instance = new $related;
return new HasMany($instance->newQuery(), $this, $foreignKey);
}
/**
* Define an inverse one-to-one or many relationship.
*
* @param string $related
* @param string $foreignKey
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function belongsTo($related, $foreignKey = null)
{
list(, $caller) = debug_backtrace(false);
// 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';
}
// 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;
$query = $instance->newQuery();
return new BelongsTo($query, $this, $foreignKey, $relation);
}
/**
* Get a new query builder instance for the connection.
*
......
<?php namespace Jenssegers\Mongodb\Relations;
class BelongsTo extends \Illuminate\Database\Eloquent\Relations\BelongsTo {
/**
* Set the base constraints on the relation query.
*
* @return void
*/
public function addConstraints()
{
// For belongs to relationships, which are essentially the inverse of has one
// or has many relationships, we need to actually query on the primary key
// of the related models matching on the foreign key that's on a parent.
$key = $this->related->getKeyName();
$this->query->where($key, '=', $this->parent->{$this->foreignKey});
}
/**
* Set the constraints for an eager load of the relation.
*
* @param array $models
* @return void
*/
public function addEagerConstraints(array $models)
{
// We'll grab the primary key name of the related models since it could be set to
// a non-standard name and not "id". We will then construct the constraint for
// our eagerly loading query so it returns the proper models from execution.
$key = $this->related->getKeyName();
$this->query->whereIn($key, $this->getEagerModelKeys($models));
}
}
\ No newline at end of file
<?php
require_once('vendor/autoload.php');
require_once('models/User.php');
require_once('tests/app.php');
use Jenssegers\Mongodb\Facades\DB;
......
<?php
require_once('vendor/autoload.php');
require_once('tests/app.php');
use Jenssegers\Mongodb\Facades\DB;
......
<?php
require_once('vendor/autoload.php');
require_once('models/User.php');
require_once('tests/app.php');
use Jenssegers\Mongodb\Connection;
use Jenssegers\Mongodb\Model;
use Jenssegers\Mongodb\DatabaseManager;
class ModelQueryTest extends PHPUnit_Framework_TestCase {
public function setUp()
......
<?php
require_once('vendor/autoload.php');
require_once('models/User.php');
require_once('models/Soft.php');
require_once('models/Book.php');
require_once('tests/app.php');
use Jenssegers\Mongodb\Connection;
use Jenssegers\Mongodb\Model;
use Jenssegers\Mongodb\DatabaseManager;
class ModelTest extends PHPUnit_Framework_TestCase {
public function setUp() {}
......
<?php
require_once('vendor/autoload.php');
require_once('tests/app.php');
use Jenssegers\Mongodb\Facades\DB;
......
<?php
require_once('tests/app.php');
class RelationsTest extends PHPUnit_Framework_TestCase {
public function setUp() {
}
public function tearDown()
{
User::truncate();
Book::truncate();
Item::truncate();
Role::truncate();
}
public function testHasMany()
{
$author = User::create(array('name' => 'George R. R. Martin'));
Book::create(array('title' => 'A Game of Thrones', 'author_id' => $author->_id));
Book::create(array('title' => 'A Clash of Kings', 'author_id' => $author->_id));
$books = $author->books;
$this->assertEquals(2, count($books));
$user = User::create(array('name' => 'John Doe'));
Item::create(array('type' => 'knife', 'user_id' => $user->_id));
Item::create(array('type' => 'shield', 'user_id' => $user->_id));
Item::create(array('type' => 'sword', 'user_id' => $user->_id));
Item::create(array('type' => 'bag', 'user_id' => null));
$items = $user->items;
$this->assertEquals(3, count($items));
}
public function testBelongsTo()
{
$user = User::create(array('name' => 'George R. R. Martin'));
Book::create(array('title' => 'A Game of Thrones', 'author_id' => $user->_id));
$book = Book::create(array('title' => 'A Clash of Kings', 'author_id' => $user->_id));
$author = $book->author;
$this->assertEquals('George R. R. Martin', $author->name);
$user = User::create(array('name' => 'John Doe'));
$item = Item::create(array('type' => 'sword', 'user_id' => $user->_id));
$owner = $item->user;
$this->assertEquals('John Doe', $owner->name);
}
public function testHasOne()
{
$user = User::create(array('name' => 'John Doe'));
Role::create(array('type' => 'admin', 'user_id' => $user->_id));
$role = $user->role;
$this->assertEquals('admin', $role->type);
}
}
\ No newline at end of file
<?php
$loader = require 'vendor/autoload.php';
$loader->add('', 'tests/models');
use Jenssegers\Mongodb\Connection;
use Jenssegers\Mongodb\Model;
use Jenssegers\Mongodb\DatabaseManager;
......
......@@ -9,4 +9,9 @@ class Book extends Eloquent {
protected static $unguarded = true;
protected $primaryKey = 'title';
public function author()
{
return $this->belongsTo('User', 'author_id');
}
}
\ No newline at end of file
<?php
use Jenssegers\Mongodb\Model as Eloquent;
class Item extends Eloquent {
protected $collection = 'roles';
protected static $unguarded = true;
public function user()
{
return $this->belongsTo('User');
}
}
\ No newline at end of file
<?php
use Jenssegers\Mongodb\Model as Eloquent;
class Role extends Eloquent {
protected $collection = 'roles';
protected static $unguarded = true;
public function user()
{
return $this->belongsTo('User');
}
}
\ No newline at end of file
......@@ -8,9 +8,19 @@ class User extends Eloquent {
protected static $unguarded = true;
public function phone()
public function books()
{
return $this->hasOne('Phone');
return $this->hasMany('Book', 'author_id');
}
public function items()
{
return $this->hasMany('Item');
}
public function role()
{
return $this->hasOne('Role');
}
}
\ No newline at end of file
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