I'm not sure if this is what is really causing my issue, but perhaps someone will know. When I use Laravel Socialite and go:
$social_user = Socialite::driver($provider)->user();
Then somewhere else in my code is do this:
if ($authUser = User::where('provider_id', $social_user->id))
return $authUser;
For some crazy reason I get an error like this:
Argument 1 passed to Illuminate\Auth\SessionGuard::login() must implement interface Illuminate\Contracts\Auth\Authenticatable, instance of Illuminate\Database\Eloquent\Builder given
However if I do this I don't get an error:
if($authUser = User::where('email', $social_user->email)->first())
return $authUser;
I log this user in like this:
Auth::login($authUser, true);
Does anyone know why? I'm using laravel 5.2
The error message is actually self explained. When you do User::where('provider_id', $social_user->id) you end up with builder object that implements Illuminate\Database\Eloquent\Builder. You can call ->get() on it to get the collection of results (a collection of objects that implements Illuminate\Contracts\Auth\Authenticatable in your case, so you can iterate over them), or as you did, you can get the first match with ->first() (one object that implement Illuminate\Contracts\Auth\Authenticatable). You can read more in the Eloquent documentation.
The main point is that until you call ->get() or ->first() you are working with builder object. There is actually ->find() method also, that is used to retrieve record by pk, you cannot use it to search for records by constraints (where), but it also returns model object.
Related
I was reading a blog related Repository Pattern. I saw use of withBlogs method.
public function index()
{
$blogs = $this->blogRepository->all();
return view('blog')->withBlogs($blogs);
}
I never see something like this before. What is the purpose of it or what it's doing?
it is laravel's magic methods
you can name the method anything you want with with() in laravel
let me explain you by example, the following code you write in your controller method
return view('index')->withName('Name')->withFullName('Full Name')->withaddress('Your address')->withcountryName('CountryName');
then you can access the values in view explained below
withName('Name') in view it becomes $name
withFullName('Full Name') in view it becomes $fullName
withaddress('Your address') in view it becomes $address
withcountryName('CountryName') in view it becomes $countryName
It is used for passing data into views. The with method returns an instance of the view object so that you can continue chaining methods before returning the view. All of the syntax below archives the same thing:
return view('blog')->withBlogs($blogs);
return view('blog')->with('blogs', $blogs);
return view('blog')->with(compact('blogs'));
return view('blog', compact('blogs'));
I would like to use the "Laravel" Auth features.
I have a middleware which finds some data, extract :
$member = $this->memberService->getMemberRolesFromLdap($accessToken, $id);
$member is an array.
Just after this research, I would like to store this $member somewhere to retrieve some data later in some other classes. Like that :
$roles = Auth::user()->roles;
So I thought it was a good opportunity to use these Auth features. But for the moment, I have this error :
Symfony\Component\Debug\Exception\FatalThrowableError: Argument 1 passed to Illuminate\Auth\SessionGuard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable, array given
So if I understand, I must declare somewhere that $member uses (or is) an instance of Authenticable. And there I admit my limits.
Is it a good idea to use Auth features to do that, and if so, how can I do that?
I tried this. It works, but I am not sure if it is best practice:
$ldapData = $this->memberService->getMemberRolesFromLdap($accessToken, $id);
// login this member
$user = new User();
$user->ldapData = $ldapData;
Auth::login($user);
And now, I can manipulate the user like that:
Auth::user()->ldapData
After I create a new user I try to create token via
$user = User::where('user_id', '=', $userid)->get();
$user->createToken('name')->accessToken;
Then i got the following error:
Method Illuminate\Database\Eloquent\Collection::createToken does not
exist.
Thanks
You are calling for a collection of users when you use the get() method, which won't have the createToken method (which is exactly what the error message is telling you).
You need to call for a single User model:
$user = User::find($userid);
And then, assuming you have the createToken method on your User model, this should work.
EDIT per comments:
You may have some other issue that is preventing the creation of the token in addition to the original issue of the collection vs an object. Try to create the token first:
$user = User::find($userid);
$token = $user->createToken('name');
Then if you will either get an error (if your createToken method is incorrect, or the parameter 'name' is not correct, etc), or you will have the token, and can then draw the accessToken from the new variable, $token.
Like this:
$accessToken = $token->accessToken
Either way, this will give you the diagnostics to bug hunt.
I try to build a path for a model on laravel
I created a function in my model:
public function path()
{
return App\Helper\GeneralController::getURL($this);
}
with dd(App\Helper\GeneralController::getURL($this)) test I got the right answer. (output is a URL)
but in view with the call: $article->path I get this error:
App\Article:: path must return a relationship instance.
What is wrong?
You need to call it:
$article->path()
When you do $article->path, you're trying to use Eloquent relationship which you don't have.
I know this has already been answered and accepted. However, if the OP did want to use a property accessor rather than a method use the "get{property name}Attribute" syntax of Laravel to create a custom attribute.
Here is what it would look like for this specific case:
public function getPathAttribute()
{
return App\Helper\GeneralController::getURL($this);
}
using this approach "path" can now be called as an attribute and will not be resolved to a relationship using the syntax:
$article->path;
You're calling a relationship.
$article->path
To call the method, use '()', like so,
$article->path()
I faced that error when I forgot to write return before relation in the model!
check it out now!
path() is method not object element you need to call as method
$article->path();
Laravel 9 introduced a new way to define accessors/mutators within a model using Illuminate\Database\Eloquent\Casts\Attribute.
https://laravel.com/docs/9.x/eloquent-mutators#defining-an-accessor
public function path(): Attribute
{
return new Attribute(fn () => GeneralController::getURL($this));
}
For future visitors from Google, all the other answers can be applicable in certain scenarios, but you might want to also look if your method access modifier, if your method is protected and you try to call it you will be welcome with this error. You need change your method to public.
I am working with laravel 4.2 and have table in db with property is_active.
When I try to access this model property:
$model->is_active
I am getting following error:
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
So question is how to access this property?
Please do not recommend to rename this field in the database if possible because this is already existing database in production.
Here is my model class:
class Position extends \Eloquent {
protected $table = "hr_positions";
protected $fillable = ['slug', 'info_small', 'info_full', 'is_active', 'start_date', 'end_date', 'tags', 'user_create_id', 'user_update_id'];
use \MyApp\Core\StartEndDateTrait;
public function postulations(){
return $this->hasMany('Postulation', 'position_id', 'id');
}
}
Latest notice:
All this error ocurrs on a page where I am creating my entity. In the controller before forwarding to the page I am doing:
$position = new \Position();
and then, for example, following code produce error as well:
dd(($position->getAttribute('is_active')));
but if I replace $position = new \Position(); with
$position = \Position::first();
error is gone?
What is going on here?????
Laravel does a lot of magic behind the scenes, as in, calls a lot of php magic methods.
If a called property is not defined, __call is invoked which in Eloquent calls getAttribute().
Steps taken by getAttribute($key) are
Is there a database field by this key? If so, return it.
Is there a loaded relationship by this key? If so, return it.
Is there a camelCase method of this key? If so, return it. (is_active looks for isActive method)
Returns null.
The only time that exception is thrown is in step 3.
When you create a new instance, eloquent has no idea what kind of fields it has, so if you have a method by the same name, it will always throw a relation error, this seems to be the case in both Laravel4 and Laravel5.
How to avoid it? Use the getAttributeValue($key) method. It has no relation checks and returns null by default.
Alternatively you can also add a get mutator for your field.
I have found a hack for this. Still not ideal but at least I have some solution. Better any than none.
So This code produce problem:
$position = new \Position();
if($position->is_active){
//
}
and this one works fine, this is solution even hacky but solution:
$position = new \Position(['is_active' => 0]);
if($position->is_active){
//
}
I will wait if someone give better, cleaner solution. If no one comes in next few days I will accept mine.