Laravel Join Query returning empty column - mysql

I have a member table with some entries. Each member can create a user account in laravel's users table.
They each have a field called "person_id" and that's how the connection is made.
I have a search that returns a list with all of them. I have a checkbox "Search only registered" that means it returns only members that have users account, otherwise if the check doesn't check, return a mix with all of them.
The thing is, no matter if the checkbox is checked or not, the person_id must be pulled for each one.
if($reg == 'on') {
$Members = $Members->rightJoin('users', 'users.person_id', '=', 'members.person_id');
}
else {
$Members = $Members->leftJoin('users', 'users.person_id', '=', 'members.person_id');
}
I tried with leftJoin but person_id comes empty

at first look if you are using Eloquent i can tell you are missing the "->get();" at the end of each query.
Hope this helps.

Use relation in member model:
public function user()
{
return $this->belongsTo('App\User', 'person_id', 'person_id' );
}
public function getMemberWithUser()
{
return $this->select('*')->with('user')->get()->toArray();
}
and use (new Member)->getMemberWithUser(); in controller. That will return you member detail with user.

Neverming guys I found it out.
Most members don't have yet a user account, only 2. And the select wasn't specifying which table to take the person_id from. And with most members missing an user account, it was trying to get it from users.
I did this:
$Participants = Member::select(
'members.first_name',
'members.last_name',
'members.person_id',
'members.email'
);

Related

Laravel SQL Query. Help me

I have a table name "Offers" with 3 (public, request, private ) types of data. Now I want to show directly to the user end public and request offers. and private offers not be shown but when admin will add user_id and offer_id in a new table (offer_access) then the private offer should be available to user end for only these users.
$offer = Offer::where('status', 'public')->orWhere('status', 'request')->latest()->get();
I wrote this one and getting public and private offers for user end. Now I want to show private offers to a user when it available on "OfferAccess" table.
So now, How can I write the SQL query for that?
You can try blow:
$offer = Offer::whereIn('status', ['public', 'request'])
->orWhere(function($query) {
$query->where('status', 'private')
->whereHas('OfferAccess', function($qry) {
$qry->where('user_id', auth()->user()->id);
});
})->get();
If you need only the latest results can use ->latest()->get() instead of only ->get().
Also if you need to get it for any other user than the current logged in user, then you need to pass user_id to closure function. so you need to use updated orWhere like as:
->orWhere(function($query) use ($user_id) {
$query->where('status', 'private')
->whereHas('OfferAccess', function($qry) use ($user_id) {
$qry->where('user_id', $user_id);
});
})
It should give you the desired results.

Laravel: hasMany relationship + where condition fails

I have a Customer Eloquent model. Customer can have multiple WishLists where he / she can add some products. Typical ecommerce functionality.
The point is that Customer can belong to many Users models.
This was easy:
public function users()
{
return $this->belongsToMany(User::class, 'users_sync_customers', 'customer_uuid', 'user_id')
->withTimestamps()
->orderBy('last_name', 'asc');
}
So I can get all Customers assigned for logged in user by
auth()->user()->customers 🎉
As I mentioned, Customer can have multiple Wishlists:
public function wishLists()
{
return $this
->hasMany(WishList::class, 'customer_uuid', 'uuid')
->where('user_id', '=', auth()->user()->id); // <----- this will fail when I log out
}
but WishList is scoped to both Customer UUID and User ID.
Above relationship works but only when I'm logged in obviously.
As soon as I log out the auth()->user()->is is NULL and I get:
ErrorException {#1483 #message: "Trying to get property 'id' of
non-object"
Question: How can I reference in wishLists() the user_id value?
WishList model has this:
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
So can I use something like $this->user->id?
edit:
Nope, this also doesn't work.
you must check that the user is logged in?
Auth::check() ? Auth::user()->id : null

Laravel multiple joins using scope to check every record if it has a value

I have 3 tables, the first is 'Event' table with columns:
id
showname
eventdate
office_id //the office that made this
photo
user_id //the user that saved the record
...
and some other columns.
The office_id is foreign key in offices below
The second is 'Offices' table
id
name
address
owner_id //the user owner of Office
...
and some other columns.
The owner_id is foreign key in Users below
and the third is 'Users' table
id
name
...
and some other columns.
Now I am trying in an index view file to show the events.
I made that using a scope in Events model that showed the Events that belongs to the signed_in User.
public function scopeHasMyOffice($query, $me)
{
return $query->join('offices', function ($join) use ($me) {
$join->on('events.foffice_id', '=', 'offices.id')
->where('owner_id', $me);
});
}
In the controller, I wrote this code
public function myindex()
{
$my = Auth::User()->id;
if (!is_null($my))
{
$events = Event::HasMyOffice($my)->select('events.*')
->orderby('eventdate', 'desc')
->get();
}
else
{
$events = NULL;
}
}
That works and gives the list of the events whose owner is the user connected.
I have 2 other lists that show all events of the state and the city.
Now I want to show in front of every row a button 'View' that is easy and a button 'Edit' if the event belongs to the office that owner is the user signed in
Only this user can have the option to edit the record.
And this is build for one user (one owner) per office. If they are more I must change it again.
Anyway now I want to do the Edit button but only for the user owners as I explained and need some help.
I thought a nice idea to add to the model Events this code
public function scopeInMyOffice($query, $me, $gid)
{
return $query->join('offices', function ($join) use ($me) {
$join->on('events.foffice_id', '=', 'office.id')
->where('owner_id', $me);
})->where('event.id', $gid);
}
to check every row if it happens but that didnt work.
#if( count($event->InMyOffice(Auth::user()->id, $event->id)) > 0)
Edit
#endif
So I am stuck and need some help.

How Eloquent work with Relationship?

I'm new to laravel relationship so many apologizes if it's just dumb question. I'm using a pivot table named users_email on the project to get Emails of users. Pivot table contains the foreign key Uid and Email_id. Uid references users table
primary key and the same as Email_id. I can get the result while joining them using QueryBuilder.
$recent_inbox_email=DB::table('users_email')->
join('email','users_email.email_id','=','email.Id')->
join('users','users_email.Uid','=','users.Id')->
where('users_email.Uid','=',$Uid)->
where('email.draft','<>','true')->
where('email.trash','<>','true')->
where('email.status','=','unread')->count();
here's how I define the relationship in my models
public function getUid()//User Model
{
return $this->hasMany("User_Email",'Uid');
}
public function getEmId()//Email Model
{
return $this->hasMany("User_Email",'email_id');
}
//User_Email Model
public function email()
{
return $this->belongsTo('Email','Id','email_id');
}
public function user()
{
return $this->belongsTo('User','Id','Uid');
}
Now I want to query something like this using Eloquent
$query= select * from users_email inner join
email on users_email.email_id=email.Id
inner join users on users_email.Uid=users.Id
where users.Id=users_email.Uid limit 0,10
foreach($query as $emails)
{
echo $emails->f_name;
echo $emails->Message
}
DB designer Pic
Link to image
Thanks
There are no dumb questions. I'll try to give you an explanation! I'm not a pro, but maybe I can help.
Laravel uses some conventions that are not mandatory, but if you use them, things work like a charm.
For example, as a general recommendation, tables should be named in plural (your table users is ok. Your "email" table should be "emails"). The model, should be named in singular. This is User.php for table users, Email.php for table emails.
"The pivot table is derived from the alphabetical order of the related model names...", in this case "email_user". I repeat, you are not obliged to name them like this, as you can specify the table for the model setting the $table property in the model.
Once you have set up things like this, you only have to add this to your User model:
public function emails()
{
return $this->belongsToMany('Email');
}
And in your Email model:
public function users()
{
return $this->belongsToMany('User');
}
The "User" and "Email" between parentheses is the name of the related model.
And that's it. You can now do this:
$user = User::find(1);
foreach($user->emails as $email) {
echo $email->subject . '<br>';
echo $email->message . '<br>';
}
If you decide not to follow conventions, you can still use Eloquent relationships. You have to set up the relationship like this:
public function nameOfRelation()
{
return $this->belongsToMany('NameOfRelatedModel', 'name_of_table', 'foreign_key', 'other_key');
}
In the case of the User model for example:
public function emails()
{
return $this->belongsToMany('Email', 'users_email', 'Uid', 'email_id');
}
And in the email model, the other way round.
The answer got long! I didn't test the code, but this should give you an idea!
You can always check the official Laravel documentation, it is really helpful!
http://laravel.com/docs/4.2/eloquent
Hope I helped

Help with LinqtoSql

Im using the Repository pattern and I want to write a method that receives a role and returns an Iqueryable of the users that belong to that role. (Im not sure if the right way would be to receive the role object or the role_id... in any case, how can I do this?? I dont like the query structure, I prefer the method structure of linq.
users and roles is many to many with a users_roles join table.
private ClasesDataContext db = new ClasesDataContext();
public IQueryable GetByRole(Role role)
{
return db.Users.Where();
}
Maybe try something like:
public IQueryable<User> GetByRoleId(Role role) {
return db.UsersRoleJoinTable.Where(ur => ur.Role == role).select(ur => ur.User);
}
Where UsersRoleJoinTable is your many-to-many join table.
Hope it helps.
Update: the select(ur => ur.User) is telling linq that for every row returned by "db.UsersRoleJoinTable.Where(ur => ur.Role == role)" we want to get the user associated with the UsersRoleJoinTable object. If you wanted a list of user ids instead, you could tell linq to select only user.id by doing select(ur => ur.id). Think of linq's select as a some sort of "for every row do this and put it in the list returned instead of the original row"
There is one downside to this approach tho, I believe in this case Linq is generating the sql to get the rows from the Join table (UsersRoleJoinTable) and then for every row returned, is executing another query to look up the User. I might be wrong on this, so to check the SQL generated by Linq do:
string sql_query = db.UsersRoleJoinTable.Where(ur => ur.Role == role).select(ur => u.User).ToString();
and then print the value of sql_query or watch it in debug mode. If Linq is in fact doing multiple queries, then I think the best solution is to create a view or stored procedure in SQL Server to get the users associated with the role and then add the view or stored procedure to Visual Studio designer so that you can call the view like:
db.GetUsers(role_id) //if using a GetUsers stored procedure
or
db.UsersByRoleView.where(ur => ur.role_id == passed_role_id) //if using a UsersByRoleView view
If you have an instance of the Role object
public IQueryable<User> GetByRole(Role role) {
return db.Users.Where(u => u.Role == role);
}
would work.
If you don't but just know the Id or some other property of the role something like this might be better.
public IQueryable<User> GetByRoleId(int roleId) {
return db.Users.Where(u => u.Role.Id == roleId);
}