Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel inserting and retrieving relationships

I'm working on a project built on Laravel 3, and I'm trying to see if I can shorten the code for working with relationships (better ways of doing the following)

user controller

create user function

$newUser = new User;

if($userData['organization'])
    $newUser->organization = self::_professional('Organization', $newUser, $userData);
else
    $newUser->school = self::_professional('School', $newUser ,$userData);

create or retrieve school/organization id

private function _professional($type, $newUser, $userData)
{
    if ( $orgId = $type::where('name', '=', $userData[strtolower($type)])->only('id'))
        return $orgId;
    else
    {
        try {
            $org = $type::create(array('name' => $userData[strtolower($type)]));
            return $org->attributes['id'];
        } catch( Exception $e ) {
            dd($e);
        }
    }
}

Models

User model

class User extends Eloquent {

    public function organization()
    {
        return $this->belongs_to('Organization');
    }

    public function school()
    {
            return $this->belongs_to('School');
    }
}

Organization/School model

class Organization extends Eloquent {

    public function user() 
    {
        return $this->has_many('User');
    }

}

Migrations

Users migration

....
$table->integer('organization_id')->unsigned()->nullable();
$table->foreign('organization_id')->references('id')->on('organizations');

$table->integer('school_id')->unsigned()->nullable();
$table->foreign('school_id')->references('id')->on('schools');
....

Organizations/Schools migration

....
$table->increments('id');
$table->string('name');
$table->string('slug');
$table->integer('count')->default(1)->unsigned();
....

Now, my questions are:

  1. Is there any better way of generating the User -> School/Organization relationship, then the one used above? If so, how?

  2. Any better way of retrieving the User's School/Organization name then by doing: School::find($schoolId)->get()

Doing User::find(1)->school() won't retrieve any data for school, only:

[base:protected] => User Object
(
    [attributes] => Array
        (
            [id] => 1
            [nickname] => w0rldart
            ....
            [organization_id] => 
            [school_id] => 1
            ...
        )
    [relationships] => Array
        (
        )

    [exists] => 1
    [includes] => Array
        (
        )

)

[model] => School Object
(
    [attributes] => Array
        (
        )

    [original] => Array
        (
        )

    [relationships] => Array
        (
        )

    [exists] => 
    [includes] => Array
        (
        )

)
like image 236
Alex Avatar asked Jun 10 '13 19:06

Alex


2 Answers

// You have to save this before you can tied the organizations to it
$new_user->save();

// The organizations that you want to tie to your user
$oganization_ids = array(1, 2, 3);

// Save the organizations
$result = $new_user->organization()->sync($oganization_ids);
like image 200
coffe4u Avatar answered Sep 23 '22 17:09

coffe4u


Is there any better way of generating the User -> School/Organization relationship, then the one used above? If so, how?

Eloquent should be able to handle it automatically, see here: http://three.laravel.com/docs/database/eloquent#inserting-related-models.

Any better way of retrieving the User's School/Organization name then by doing: School::find($schoolId)->get()

If you mean you can't retrieve the relationship information: has_name and belongs_to return an Elloquent Expression, you still need to call get() on them to retrieve the object or the collection you want.

The way I've coped with this is adding an argument for relationships to determine if the method should return an expression or a result:

$table->increments('id');
$table->string('name');
$table->string('slug');
$table->integer('count')->default(1)->unsigned();
$table->unique('name');

...

class User extends Eloquent
{
    /**
     * Return an Elloquent Expression or a collection (or object)
     * Defaults to return a collection
     */
    public function organization ($as_expression=FALSE) {
        $related = $this->belongs_to('Organization');
        return $as_expression ? $related : $related->get();
    }

    public function school ($as_expression=FALSE) {
        $related = $this->belongs_to('School');
        return $as_expression ? $related : $related->get();
    }

    ...

    public function create ($user_data=array()) {
        $newUser = new User;
        $activity = @$user_data['organization'] ?
            'organization' : (@$user_data['school'] ? 'school' : '');

        switch ($activity) {
            case 'organization':
            case 'school':
                /**
                 * Call the corresponding method, return as Eloquent Expression
                 * Use a string to be verbose, TRUE does fine if wanted
                 */
                $new_user->{$activity}('as_expression')->save(array( 'name' => $user_data[$activity]));

                break;
            default:
                break;
        }

        return $new_user;
    }
}

...

class Organization extends Eloquent
{
    public function user ($as_expression=FALSE) {
        $related = $this->has_many('User');
        return $as_expression ? $related : $related->get();
    }
}
like image 33
Ast Derek Avatar answered Sep 20 '22 17:09

Ast Derek