Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel: Pass Parameter to Relationship Function?

Tags:

php

laravel

Is it possible to pass, somehow, a parameter to a relationship function?

I have currently the following:

public function achievements()
{
     return $this->belongsToMany('Achievable', 'user_achievements')->withPivot('value', 'unlocked_at')->orderBy('pivot_unlocked_at', 'desc');
}

The problem is that, in some cases, it does not fetch the unlocked_at column and it returns an error.

I have tried to do something like:

public function achievements($orderBy = true)
{
$result = $this->belongsToMany (...)
if($orderBy) return $result->orderBy(...)
return $result;
}

And call it as:

$member->achievements(false)->(...)

But this does not work. Is there a way to pass parameters into that function or any way to check if the pivot_unlocked_at is being used?

like image 367
user2840318 Avatar asked Apr 11 '14 15:04

user2840318


3 Answers

Well what I've did was just adding new attribute to my model and then add the my condition to that attirbute,simply did this.

Class Foo extends Eloquent {
    protected $strSlug;

    public function Relations(){
         return $this->belongsTo('Relation','relation_id')->whereSlug($this->strSlug);
    }
 }

 Class FooController extends BaseController {
     private $objFoo;


     public function __construct(Foo $foo){
         $this->objFoo = $foo
     }

     public function getPage($strSlug){
        $this->objFoo->strSlug = $strSlug;
        $arrData = Foo::with('Relations')->get();
        //some other stuff,page render,etc....
     }
 }
like image 134
Hrach Avatar answered Nov 06 '22 05:11

Hrach


You can simply create a scope and then when necessary add it to a builder instance.

Example:

User.php

public function achievements()
{
    return $this->hasMany(Achievement::class);
}

Achievement.php

public function scopeOrdered(Builder $builder)
{
    return $builder->orderBy(conditions);
}

then when using:

//returns unordered collection
$user->achievements()->get();

//returns ordered collection
$user->achievements()->ordered()->get();

You can read more about scopes at Eloquent documentation.

like image 22
ethris Avatar answered Nov 06 '22 04:11

ethris


You can do more simple, and secure:

When you call the relation function with the parentesis Laravel will return just the query, you will need to add the get() or first() to retrieve the results

public function achievements($orderBy = true)
{
if($orderBy) 
    $this->belongsToMany(...)->orderBy(...)->get();
else
    return $this->belongsToMany(...)->get();
}

And then you can call it like:

$member->achievements(false);

Works for the latest version of Laravel.

like image 22
Julio Popócatl Avatar answered Nov 06 '22 03:11

Julio Popócatl