laravel: how to pass a parameters to a function in model? - laravel

I'm using laravel 5.5 / php 7.2 /
for example, I have a function like this in a model:
public function featuredTopSight($count=8)
{
return $this->hasMany(Sight::class)
->wherePublish(1)
->latest()
->take($count);
}
and then, In view:
$sight->featuredTopSight(8);
But I got this error:
"htmlspecialchars() expects parameter 1 to be string, object given
but with $sight->featuredTopSight; I got right answer. but I can not pass the parameter.

In that function you're defining a relationship.
You can't call a relationship with arguments.
First you need to declare the relation, and then the query or method to retrieve results.
Your method should be something similar to:
public function sights()
{
return $this->hasMany(Sight::class);
}
public function getFeaturedTopSights($count = 8)
{
return $this->sights()->wherePublish(1)->latest()->take($count)->get();
}

Related

Laravel 5.8 query scope

I am learning laravel and I encountered this problem where when I use query scope my code returns zero data. The database has got data.
It is kinda confusing because I think I have done everything right as per the tutorial
Scope:
public static function scopeLatest($query)
{
return $query->orderBy('id', 'asc')->get();
}
Controller:
public function index()
{
$posts = Post::Latest();
return view('posts.index', compact('posts'));
}
AFAIK, you won't be able to use scopeLatest as Laravel already has a latest() method on its query builder.
As for the scope you tried to make, here are a few pointers:
a scope shouldn't be defined as static method
you shouldn't actually call get() inside your scope
You don't need to return from the scope.
So even though this scope won't actually work (because of the name), as an example, this is what is would look like based on your question:
public function scopeLatest($query)
{
$query->orderBy('id', 'desc'); //desc should put the latest first
}
Your controller method (in either case) should be:
public function index()
{
$posts = Post::latest()->get();
return view('posts.index', compact('posts'));
}

How to add a condition to a eloquent relation

This is the case I have
$user = User_picture::where('is_main','=',1)->where('user_id','=',Auth::user()->id);
This means a user has many pictures but there is only one picture that has is_main value 1.
I tried this.
public function active_picture()
{
return $this->hasMany('App\User_picture')->find($this->is_main);
}
This doesn't return anything but an error that says it should be an object. Can anyone help me out with the case?
HasMany is meant to return a collection since it is a one to many relationship method.
If you only want to return one result, you should use HasOne with conditions. To define conditions, you use where() not find(). Find() is only used to match the model's primary key.
public function active_picture()
{
return $this->hasOne('App\User_picture')
->where('is_main', 1);
}
You could declare an accessor like:
In User model:
// declare relationship:
public function pictures()
{
return $this->hasMany(Picture::class);
}
// declare accessor:
public function getMainPictureAttribute()
{
return $this->pictures()->where('is_main', 1)->first();
}
So you can do this:
auth()->user()->main_picture ...

Laravel Model Binding

I have issue with model binding in routes and controller. Here is my routes:
Route::group(['prefix'=>'services/devops/domain-names'], function () {
Route::group(['middleware'=>'auth'], function () {
Route::get('/editAutoRenew/{domainname}', 'EnomController#editAutoRenew');
});
Route::post('/', 'EnomController#checkDomainName');
});
And here is function
public function editAutoRenew(DomainName $domainname)
{
dd($domainname);
}
But this gives me empty model. Why? How can I get my model?
I tried to route:list and there it shows {domainname}
You get in argument integer type, not object. Try to rewrite your function with:
public function editAutoRenew($domainname)
{
$domainnameObj = DomainName::findOrFail($domainname);
}
When you use:
DomainName::first();
You get all entries from your table domain_name, then command first() - get first of this records.

Error when using Laravel 5.4 Seeder Function

Type error: Argument 1 passed to
Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an
instance of Illuminate\Database\Eloquent\Model, instance of
Illuminate\Database\Eloquent\Collection given
I am planning to generate Fake date for user with profile. I have two model: User & Profile. I have done the relationship with each others. But when i execute it and the problems came. Above is the error when i running Seeder.
This is the class that found bug.
public function run()
{
factory(App\User::class, 40)->create()->each(
function($user) {
$user->profile()->save(
factory(App\Profile::class, 1)->make()
);
}
);
}
I guess you are using Laravel 5.4.
The has been a modification in the factory() helper method. From the docs:
The factory Helper
Calling factory(User::class, 1)->make() or factory(User::class, 1)->create() will now return a collection with one item. Previously, this would return a single model. This method will only return a single model if the amount is not supplied.
Laravel 5.3 to 5.4 updgrade guide
That means that you should remove the 1 from your factory() call.
public function run(){
factory(App\User::class, 40)->create()->each(
function($user) {
$user->profile()->save(
factory(App\Profile::class)->make()
);
}
);}
Edit 1: You have to change this line:
factory(App\Profile::class, 1)->make()
To this
factory(App\Profile::class)->make()
Getting the relation $user->profile() by calling the method, will return the related models as a Collection. You can do $user->profile()->first() to get a single result of type Illuminate\Database\Eloquent\Model or just $user->profile without the ().

Laravel relationship `whereNotIn` other table

I am trying to return all Posts(Model:Post) which have no row in the PostsHistory Model.
My code is:
public function posts(){
return $this->hasMany('App\Post');
}
public function remaining_posts(){
$history = PostHistory::all()->pluck('id');
return $this->posts->whereNotIn('post_id', $history);
}
But I get an error
[BadMethodCallException]
Method whereNotIn does not exist.
Is there any way I could get the remaining_posts through a relationship or can only be done in the controller?
Edit your last line to:
return $this->posts()->whereNotIn('post_id', $history)->get();
i.e.
You need to change posts to posts(). posts is a Illuminate\Database\Eloquent\Collection object which does not have whereNotIn() method where as posts() will return a Illuminate\Database\Eloquent\Relations\HasMany object which has whereNotIn() method defined.
whereNotIn() returns a Illuminate\Database\Query\Builder object. So you need to call get() to get a collection. But if you want the flexibilty to chain other Builder methods to your remaining_posts() method, do not use get().

Resources