Get user without email column - laravel

I have a database from which I fetch comments and data about the author.
I use axios to download asynchronous comments together with the author of the comment.
User.php
public function comments() {
return $this->hasMany('App\Comment');
}
Comment.php
public function author()
{
return $this->belongsTo('App\User', 'user_id');
}
CommentController.php
public function fetch(Request $request)
{
$comments = Comment::with('author')
->orderByDesc('id')
->get();
return response($comments, 200);
}
I would like to fetch only comment.author.name and comment.author.avatar . Is there any other way than hiding fields? I think that I will need the other fields in other methods.
User.php
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'email', 'password', 'remember_token',
];

you can specify wich columns you have selected on eager loading like this :
Comment::with(['author'=>function($query){
$query->select('name','avatar');
}])->get();
or simply :
Comment::with('author:name,avatar')->get()

Related

Laravel 8 : How to create a Pivot Model with its associated migration?

I would like to create a model: FormsUser and the migration: forms_user
To use the table as a pivot because I have problems when I create a forms I am told that the table: 'forms_users does not exist' because I created the migration separately and
when I go to my group members management page I get the error: 'forms_users does not exist' because here I have to use a pivot table so it must have this table name...
Can you help me to solve this problem or suggest an alternative?
in short I want to create a forms and I create a team where I can add other user to the same forms.
migration: forms && Models Forms :
class Forms extends Model
{
use HasFactory;
use SoftDeletes;
protected $fillable = [
'title',
'description',
'date',
'color',
'progress',
'user_id',
'groupe_id',
'formulaire',
'logo',
];
protected $dates = [
'created_at',
'deleted_at',
'started_at',
'update_at'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function usersGroupe()
{
return $this->belongsToMany(User::class);
}
}
migration: users && Models User:
class User extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
use SoftDeletes;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'lastname',
'firstname',
'email',
'password',
'current_team_id',
'profile_photo_path',
'role_id',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
'two_factor_recovery_codes',
'two_factor_secret',
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = [
'profile_photo_url',
'role_id',
];
protected $dates = [
'created_at',
'deleted_at',
'started_at',
'update_at'
];
public function forms()
{
return $this->hasMany(Forms::class);
}
public function formGroupe()
{
return $this->belongsToMany(Forms::class);
}
public function role()
{
//return $this->hasMany(Role::class, 'id', 'role_id');
return $this->hasOne(Role::class, 'id', 'role_id');
}
public function user()
{
return $this->hasOne(User::class);
}
}
migration: formuser && Models FormsUser :
class FormsUser extends Model
{
use HasFactory;
protected $fillable = [
'forms_id',
'user_id'
];
}
migration create_forms_user :
Schema::create('forms_user', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->unsignedBigInteger('forms_id');
$table->foreign('forms_id')->references('id')->on('forms');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
So traditionally you don't have to create a pivot model. Laravel has some naming conventions that if you stick to will make things a bit easier. For example, Models should be singular but table names should be plural except for the pivot table. For example, your models should look like so:
class User extends Model { ... }
class Form extends Model { ... }
Then your table names would be :
users
forms
form_user
The pivot table should include the singular name of each table in alphabetical order. So F comes before U in the alphabet so it should read form_user.
Lastly in your Form model you would include a 'belongsToMany' function:
public function users() {
return $this->belongsToMany('App\User');
}
and in the User Model you would include the same in reverse:
public function forms() {
return $this->belongsToMany('App\Form');
}
If you entered the migrations correctly you will never need to create a pivot model. You can simply call the other objects through the relation to retrieve an array. ie:
$user->forms
$form->users
After a lot of hard work I was finally able to solve the problem so instead of storing the data via the Models pivot I did it directly via a request to the migration.
Anyway, thanks for your participation.
Problem solved!

getting error when applied WHERE clause on a model(parent) and then gets its related model(child) data in eloquent

I have a User model which is a parent and Project model which is a child. I created a one-to-many relationship between these two like below.
User Model:
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function projects(){
return $this->hasMany('App\Project', 'user_id');
}
}
Project Model:
class Project extends Model
{
// Table Name
protected $table = 'projects';
//Primary Key
protected $primaryKey = 'project_id';
// Timestamps
public $timestamps = true;
protected $guarded = [];
public function user(){
return $this->belongsTo('App\User', 'user_id');
}
}
when applying where clause on user model and then getting its related projects:
class HomeController extends Controller
{
public function createProject(Request $request){
$client = User::where('email', $request->input('client'))->projects;
}
}
getting error
Exception
Property [projects] does not exist on the Eloquent builder instance.
but when doing
$client = User::find(id)->projects;
above query is giving me results.
Result Expected: i want to get the User model data by WHERE() clause instead of Find() clause and then gets its related projects.
As the Error Says that you dont have property in the Builder
$client = User::where('email', $request->input('client'))->projects;
try this
$client = User::with('projects')->where('email', $request->input('client'))->first()->projects;
here we are getting the user with the specific email and loading the realtion and here you get the relation as object
The source of your issue is that you have not yet retrieved any users. Before calling first() or get() on the query builder, you are limited to functions of the query builder.
Short version: call first() before accessing the projects
$client = User::query()
->where('email', $request->input('client'))
->first()
->projects;
Optional: add with('projects') to eager load the projects. This doesn't add any performance bonus in your case though, as you are only loading a single model.
class HomeController extends Controller
{
public function createProject(Request $request){
$client = User::with('projects')->where('id');
}
}
In HomeController this line will retrun collection of array.... In simple words it will return multiple records....
$client = User::where('email', $request->input('client'))->projects;
As you want single record use first (). To retrive single record... It will retrun first matching record...
$client = User::where('email', $request->input('client'))->first()->projects;

Laravel getting information from other table

I have the following tables user table, post table and profile table. the post belongs to a user and the profile belongs to a user. I also have a forum were people can post I want the users username to show instead of their name. But The username is in the profiles table and I don't know how to get it.
here is my code
class Post extends Model
{
//
public function users(){
return $this->belongsToMany('App\User','posted_by');
}
class Profile extends Model
{
//
public function users(){
return $this->belongsTo('App\User','whos_profile');
}
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'firstname','lastname', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function profile(){
return $this->hasOne('App\Profile');
}
public function post(){
return $this->hasMany('App\Post');
}
}`enter code here`
You can get it as follows
$user = User::find($id);
if($user->profile){
echo $user->profile->username;
}
You should try this:
$rsltUsers = User::with(['profile','post'])->where('id',$id)->get();
foreach($rsltUsers as $rsltUsers){
dd($user->profile->username);
}

Do something before saving model to database in Laravel 5.1

How can I do something such as modify some data fields or more validate before writing data to database in Laravel 5.1 model ?
It's document about that problem is hard to use in real application: http://laravel.com/docs/5.1/eloquent#events
My code is
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Helpers\Tools as Tools;
class Atoken extends Model
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'atoken';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'token',
'user_id',
'role',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
];
public static function newToken($userId, $role){
# Remove all token assoiciate with input user;
Atoken::where('user_id', $userId)->delete();
$params = [
'user_id' => $userId,
'role' => $role,
];
Atoken::insert($params);
$item = Atoken::where('user_id', $userId)->first();
return $item->token;
}
protected static function boot(){
static::creating(function ($model) {
$model->token = 'sometoken';
});
}
}
In this case, I always got error:
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column \"token\" violates not-null constraint (SQL: insert into \"atoken\" (\"user_id\", \"role\") values (2, USER))
How can I fix it?
class Lunch extends Eloquent
{
protected static function boot()
{
static::creating(function ($model) {
$model->topping = 'Butter';
return $model->validate();
});
}
protected function validate()
{
// Obviously do real validation here :)
return rand(0, 1) ? true : false;
}
public static function newToken($userId, $role)
{
static::where('user_id', $userId)->delete();
return static::create([
'user_id' => $userId,
'role' => $role,
])->token;
}
}
I would recommend to go into EventServiceProvider, and register event listeners
public function boot(DispatcherContract $events)
{
parent::boot($events);
// Register Event Listeners
\App\Product::updating(function ($product) {
$product->onUpdating();
});
...
then create function onUpdating within the model. You also can choose from saving, saved, creating, created, updating, updated..
This documentation has more:
https://laravel.com/docs/5.1/eloquent#events

Laravel Trying to get property of non-object

I am struggling to understand how laravel works and I have a very difficult time with it
Model - User.php the User model
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $fillable = array('email' , 'username' , 'password', 'code');
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
public function Characters()
{
return $this->hasMany('Character');
}
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
Model - Character.php the character model
<?php
class Character extends Eloquent {
protected $table = 'characters';
protected $fillable = array('lord_id','char_name', 'char_dynasty', 'picture');
public function user()
{
return $this->belongsTo('User');
}
public function Titles()
{
return $this->hasMany('Title');
}
}
?>
routes.php
Route::group(array('prefix' => 'user'), function()
{
Route::get("/{user}", array(
'as' => 'user-profile',
'uses' => 'ProfileController#user'));
});
ProfileController.php
<?php
class ProfileController extends BaseController{
public function user($user) {
$user = User::where('username', '=', Session::get('theuser') );
$char = DB::table('characters')
->join('users', function($join)
{
$join->on('users.id', '=', 'characters.user_id')
->where('characters.id', '=', 'characters.lord_id');
})
->get();
if($user->count()) {
$user = $user->first();
return View::make('layout.profile')
->with('user', $user)
->with('char', $char);
}
return App::abort(404);
}
}
In my code I will redirect to this route with the following:
return Redirect::route('user-profile', Session::get('theuser'));
In the view I just want to do:
Welcome back, {{ $user->username }}, your main character is {{ $char->char_name }}
My problem is that I will receive this error: Trying to get property of non-object in my view. I am sure it is referring to $char->char_name. What's going wrong? I have a very difficult time understanding Laravel. I don't know why. Thanks in advance!
You should be using the Auth class to get the session information for the logged in user.
$user = Auth::user();
$welcome_message = "Welcome back, $user->username, your main character is $user->Character->char_name";
You don't need to pass anything to that route either. Simply check if the user is logged in then retrieve the data. You have access to this data from anywhere in your application.
if (Auth::check())
{
//the user is logged in
$user = Auth::user();
To answer your question in the comments, reading the documentation would solve all of these problems, however:
public function user()
{
if (Auth::check())
{
$user = Auth::user();
return View::make('rtfm', compact('user'));
}
else
{
return "The documentation explains all of this very clearly.";
}
}

Categories

Resources