Laravel 5.2: how to get Model properties in a Controller - laravel-5

How can I access a Model's properties in a Controller in Laravel?
In my User model I have this array:
protected $sortable = [
'first_name',
'last_name',
'email',
];
Then, in my UserController I have:
namespace App\Http\Controllers;
...
use App\User;
class UserController extends Controller
{
public function index()
{
// here I'd like to get the $sortable array
}
}
Thank you

In your index function, you can access it by
$this->sortable
In order to do that, you must to change property accesibility to public:
public $sortable = [
'first_name',
'last_name',
'email',
];
If you insist on protected accesibility, you can create a getter function with in your model.

Dunno if i understood you well, but if you have first name, last name and email in ur DB, you can get them like this:
$user = User::all();
If not, just create it:
$user=new User();

User model
public $sortable = [
'first_name',
'last_name',
'email'
];
UserController controller
namespace App\Http\Controllers;
...
use App\User;
class UserController extends Controller
{
public function index()
{
/* user object */
$user = new User();
foreach ( $user->sortable as $item )
{
echo "{$item} <br />";
}
}
}

Related

Laravel Call to undefined method Illuminate\Database\Eloquent\Builder::privilege()

I would like to display privileges('name') instead of idPrivilege in the user collection. I have tried to add a relationship and use it in an Eloquent call but I'm getting an error.
User model
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $table = 'users';
protected $primaryKey = 'idUser';
protected $fillable = [
'name', 'email',
];
protected $hidden = [
'password', 'updated_at',
];
public function privilege()
{
return $this->hasOne(Privilege::class, 'idPrivilege', 'idPrivilege');
}
}
Privilege model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Privilege extends Model
{
protected $table = 'privileges';
protected $primaryKey = 'idPrivilege';
protected $fillable = [
'name',
];
protected $hidden = [
'updated_at',
];
public function user()
{
return $this->belongsTo(User::class, 'idPrivilege', 'idPrivilege');
}
}
UserController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class UserController extends Controller
{
public function relationTest()
{
return User::where('idUser', 1)->privilege()->get();
}
}
I'm getting the below error when I use with('privilege') to my User collection is added privilege collection.
Call to undefined method Illuminate\Database\Eloquent\Builder::privilege().
where returns a Builder instance on which a privilege method does not exist, so you can simply use it as such:
return User::find(1)->privilege()->get();;
-- EDIT
User::find(1)->with(['privilege' => function($query) {
$query->select('name');
}])->get();
I can achieve it by using resource:
$user = User::where('idUser', 1)->with('privilege')->first();
return UserResource::make($user);
Inside UserResource:
public function toArray($request)
{
return [
'idUser' => $this->idUser,
'name' => $this->name,
'email' => $this->email,
'privilege' => $this->privilege['name'],
'createdAt' => $this->created_at,
];
}
but was hoping there is simplier method of getting that.
output:
{
"data": {
"idUser": 1,
"name": "Martin",
"email": "martin#martin.martin",
"privilege": "user",
"createdAt": "2019-05-05T01:11:43.000000Z"
}
}

How to make dynamic query in laravel 5 with model and controller

i have Add query in codeigniter like this:
in controller:
$data=array(
'table'=>'tbl_activity_log',
'val'=>array(
'x'=>$x,
'y'=>$y,
'z'=>$z,
));
$log=$this->model->add_data($data);
And in model add_data function like this:
function add_data($data)
{
return $this->db->insert($data['table'],$this->security->xss_clean($data['val']));
}
But In Laravel 5 I have:
$name=$Request->input('name');
$lname=$Request->input('lname');
$myItems = array(
'first_name'=>$name,
'last_name'=>$lname
);
DB::table("tbl_user")->insert($myItems);
My question is, how can we make table field dynamic in Laravel and call that function through model.
Also, how can I call that function from model? Any help please. I want a dynamic query
You can write a helper function
//create a helper function
function addModelData($arrayData = [])
{
return \DB::table($arrayData['table'])->insert($arrayData['val']));
}
//in your controller or any place you like
$data=array(
'table'=>'tbl_activity_log',
'val'=>array(
'x'=>$x,
'y'=>$y,
'z'=>$z,
));
$log = addModelData($data);
You could create a model as described in official documentation:
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $table = 'tbl_user';
// If your primary key is not 'id'
protected $primaryKey = 'model_id';
}
Now in your controller you can use this model:
namespace App\Http\Controller;
use App\User;
use Illuminate\Http\Request;
class MyController extends Controller {
public function myAction(Request $request){
$user = new User();
$user->last_name = $request->input('lname');
$user->first_name = $request->input('name');
$user->save();
}
}
You also could use mass assignment. But before you have to set the $fillable attribute in your model:
protected $fillable = ['first_name', 'last_name'];
Now you can use mass assignment in your controller:
$user = User::create([
'first_name' => $request->input('name'),
'last_name' => $request->input('lname')
]);
// alternatively:
$user = User::create($request->only(['name', 'lname']));

Laravel default user_id attribute in Model

I have a model
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
}
I would like to set Auth::user()->id by default to user_id column. So I added:
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
public function setUserIdAttribute()
{
$this->attributes['user_id'] = Auth::user()->id;
}
}
And from my controller I'm calling for Foo::create($data) without user_id key.
But it doesn't work as expected. store() gives Integrity constraint violation because of user_id is missing. (User already logged in to achieve create page)
i cannot find official documentation about model-observers for Laravel 5.6. but you can still do it by this code
public static function boot()
{
parent::boot(); // TODO: Change the autogenerated stub
// it will automatically add authenticate user to created_by column of selected model
static::creating(function ($model){
$model->created_by = auth()->user()->id;
});
}
You provide an example where you used accessors.
https://laravel.com/docs/5.1/eloquent-mutators#accessors-and-mutators
From official doc:
The accessor will automatically be called by Eloquent when attempting to retrieve the value of first_name:
If you want to set default value for some attributes you need to use Observers.
<?php
// file app/models/Foo.php
namespace App\Models;
use App\Observers\FooObserver;
class Foo extends Model
{
protected $fillable = [
'name',
'user_id'
];
public static function boot() {
parent::boot();
parent::observe(new FooObserver);
}
}
<?php
// file app/observers/FooObserver.php
namespace App\Observers;
use App\Models\Foo;
class FooObserver {
public function creating(Foo $model) {
$this->user_id = Auth::user()->id;
}
}
About model observers in official doc:
https://laravel.com/docs/5.0/eloquent#model-observers

Argument 1 passed to Illuminate\Auth\Guard::login() must implement interface Illuminate\Auth\UserInterface, null given open:

I have facebook login which uses socialite library. The error in the question occurs when the callback occurs.
Here is my "USER" model
<?php
namespace App;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
class User extends Model implements Authenticatable
{
//use Illuminate\Contracts\Auth\Authenticatable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
use \Illuminate\Auth\Authenticatable;
public function posts()
{
return $this->hasMany('App\Post');
}
public function likes()
{
return $this->hasMany('App\Like');
}
}
The Socialite logins are handled by SocialAuthController and what i understood from the error is , auth()->login($user); , null is passed to the login("NULL"). Here is the code of SocialAuthController. What's the mistake i have made here and how to fix this. thanks in advance
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Socialite;
use App\SocialAccountService;
class SocialAuthController extends Controller
{
public function redirect($provider)
{
return Socialite::driver($provider)->redirect();
}
use \Illuminate\Auth\Authenticatable;
public function callback(SocialAccountService $service , $provider)
{
$user = $service->createOrGetUser(Socialite::driver($provider));
auth()->login($user);
return redirect()->to('/home');
}
}
The below is the handling service that will try to register user or log in if account already exists.
Here is the code of SocialAccountService.php
<?php
namespace App;
use Laravel\Socialite\Contracts\Provider;
class SocialAccountService
{
public function createOrGetUser(Provider $provider)
{
$providerUser = $provider->user();
$providerName = class_basename($provider);
$account = SocialAccount::whereProvider($providerName)
->whereProviderUserId($providerUser->getId())
->first();
if ($account) {
return $account->user;
} else {
$account = new SocialAccount([
'provider_user_id' => $providerUser->getId(),
'provider' => $providerName
]);
$user = User::whereEmail($providerUser->getEmail())->first();
if (!$user) {
$user = User::create([
'email' => $providerUser->getEmail(),
'name' => $providerUser->getName(),
]);
}
$account->user()->associate($user);
$account->save();
return $user;
}
}
}
This will try to find provider's account in the system and if it is not present it will create new user. This method will also try to associate social account with the email address in case that user already has an account.
My wild guess is that createOrGetUser() returns NULL because the SocialAccount does not have a user. So what could do is change the if condition in that method to check if the $account has a user:
public function createOrGetUser(Provider $provider)
{
...
if ( $account && property_exists($account, 'user') && $account->user ) {
return $account->user;
} else {
...

Eloquent Model has parent model

I have a Model called User with stuff like name, country and some relationships.
Now I want a Model, e.g. Vendor, having all the same functions and variables as a User including some More stuff
I thought I could to it this was:
class User extends Model implements AuthenticatableContract
{
use Authenticatable; SoftDeletes;
protected $dates = ['deleted_at', 'last_login'];
protected $fillable = [
'name',
'password',
'country',
];
protected $hidden = ['password'];
public function logs()
{
return $this->hasMany('App\Log');
}
}
And the Vendor Model:
class Vendor extends User
{
protected $fillable = [
'description'
];
public function user() {
return $this->belongsTo('App\User');
}
public function products()
{
return $this->hasMany('App\Product', 'vendor_id');
}
The Controller checks the role of the user and loads a user model or a vendor model:
if(Auth::user()->role > 1)
$user = Vendor::where('user_id', Auth::user()->id)->first();
else
$user = Auth::user();
return $user->load('logs');
But the load call fails for a vendor. I was able to join the fields of a user inside a vendor but I also need the functions of it.
The problem was that the logs function checks a field that doesn't exists.
Using this functions works:
public function logs()
{
return $this->hasMany('App\Log', 'user_id', get_called_class() !== get_class() ? 'user_id' : 'id');
}

Resources