I want to make query in laravel 5.2 to fetch agencies table which has a foreign key with organizations table using agencies.organization_id=organizations.id. Now Users table has also foreign key with organizations table using users.organization_id=organizations.id. Now how to fetch agency table that which agencies are linked with users_id.
public function postagency(Request $request) {
$user_id = $request->user_id;
$org_id = User::where('id', $user_id)->pluck('organization_id')->first();
$postagencies = agency::where('organization_id', $org_id);
echo $postagencies;
}
For what I understand is that an user can only be under one organisation and an organisation has many agencies. If not please say so and I will alter my answer.
First of all set your relationships inside your models. An example would be:
// User.php
public function organization()
{
return $this->belongsTo('App\Organization'); // App\Organization can be changed depending on the used namespace
}
More info can be found here. If you need some more examples just ask.
After you have created these relationships you can retrieve your agency like this:
$user= User::find($request->user_id);
if (!$user) ... // Check if user exists
$agencies = $user->organisation->agencies;
If I need to explain things in more detail just ask. Hope this helps :)
Related
I'm using Lumen to create an API which has to handle 2 entities: Gamemaster and Player. Both of them are actually a User of my API since they have to provide a token. So at the end, 'gamemaster' and 'player' are just an 'user' role.
So I manage them using 3 Models that handle informations from the database (I keep it simple for the example):
User:
id
username
email
password
Gamemaster:
user_id (user id as foreign key)
created_games
...
Player:
user_id (user id as foreign key)
registered_games
...
So my question is: Is it possible to merge the Model User into Gamemaster and Player? So that I can for example get a gamemaster email using Gamemaster::find($id)->email. Is there any way or I should each time search in both models to get all infos:
$user = User::find($id);
$userAsGamemaster = Gamemaster::where('user_id', '=', $id)->first();
$gamemasterName = $user->username;
$gamemasterEmail = $user->email;
$gamemasterCreatedGame = $userAsGamemaster->created_games;
use relations on model for this.
As in your case Gamemaster and Player both belongs to User so you can define relation on Gamemaster model and Player Model as following: ->
public function user(){
return this->belongsTo('App\User', 'your_foregin_key', 'Your_local_key');
}
Now You can fetch email as follows: ->
$userAsGamemaster = Gamemaster::where('user_id', '=', $id)->first();
$email = $userAsGamemaster->user->email;
Or by using:
Gamemaster::find($id)->user->email;
That's all.
Okay. I write in an answer what we had been talking about in the comments.
Not answer to the question of merge two models, but you can achive what you want defining the relationship in your models Gamemaster and Player:
public function user()
{
return $this->belongsTo(User::class);
}
So, if you have the User model id in the $id variable, you can do something like this:
$gamemaster = Gamemaster::where('user_id', $id)->first();
$gamemasterName = $gamemaster->user->username;
$gamemasterEmail = $gamemaster->user->email;
$gamemasterCreatedGame = $gamemaster->created_games;
And if in the $id variable you have the Gamemaster model id, you can do something like this:
$gamemaster = Gamemaster::find($id);
$gamemasterName = $gamemaster->user->username;
$gamemasterEmail = $gamemaster->user->email;
$gamemasterCreatedGame = $gamemaster->created_games;
And the same for the Player.
What i want to achieve?
Show user which pacts he is following.
What I am trying
I have designed two tables which are 'pacts' & 'pacts_follwers'
Table 'pacts' has the details of all the pacts
Table 'pacts_follwers' has details of users following a particular pact.
These links will give you the images of both the tables
For Schema Refer Images
So how to get pacts that user is following.
What I have tried?
Sql Query
SELECT pacts.*, (SELECT pactsid FROM pacts_follwers WHERE pacts.id = pacts_follwers.pactsid
and pacts_follwers.userid = 2 ) as pactID FROM `pacts`
Sql query Result
This query will give pactId some value, where the value is null means the user is not following that pact. If this is the solution then i would need Eloquent for this which i am unable to make.
1st table pacts
id
title
about
created_at
updated_at
pactsImage
2nd table pacts_follwers
id
pactsid
userid
created_at
updated_at
Controller Code
$pacts = DB::select("SELECT pacts.*, (SELECT pactsid FROM pacts_follwers WHERE pacts.id =
pacts_follwers.pactsid and pacts_follwers.userid = ".Auth::id()." ) as pactID FROM `pacts`");
You need to setup hasManyThrough relationship for User and Pact.
class User extends Model {
public function pacts() {
return $this->hasManyThrough(
Pact::class,
PactFollower::class
'userid',
'pactsid'
);
}
}
I don't fully understand if you want to achieve "get user's all pacts" or "if pact is followed by user". Either way, you need to setup related relationships.
Or really simple (and not efficient way)
class Pact extends Model {
public function followers() {
return $this->hasMany(PactFollower::class, 'pactsid')
}
}
Now you can use something like
$userIdsForPact = Pact::followers()->pluck('userid');
if ($userIdsForPact->has($user->id)) {
// your operation
}
Edit: For "if pact is followed by user", you need to setup belongsToThrough relationship. It doesn't come out of the box with Laravel but staudenmeir/belongs-to-through package should serve you well.
After setting the relationship properly, you can use something like this.
Pact::with('user')->get();
Or add some methods in your Pact model:
public function followedByUser($user) {
return $this->users->has($user);
}
Very silly situation, The point is I can not change the database architecture because its a running e-commerce business having more then 1m active users.
Here is my situation.
Table User:
Table Store:
Both have same primary key, mean we can call the one to one relation.
But now I have to create belongs to many relation form Store to User.
store table have two columns
slug
parentId
Now I need to get all users having slug of store
So my query is
select * from users where id IN (select id from store where slug = ?);
How can I create a relation in this situation.
Hey there i would try to answer in detail as much as possible.
Create the following relationships:
For store:
public function users(){
return $this->hasMany(User::class, 'id' ,'slug');
}
For user:
public function store(){
return $this->belongsTo(Store::class);
}
Create a new controller and write a new function as below:
public function getStoreUsers(){
$users = Store::where('slug','yourvalue')->firstOrFail()->users;
return response()->json($users);
}
The function above will return a collection of users which have theirs 'id' equals to store 'slug'
In case if you have many stores you can do the follwing:
public function getStoreUsers(){
$stores = Store::all();
$storeUsers;
foreach($stores as $store){
$users = $store->users;
$storeUsers[$store['id']] = array($users);
return response()->json($storeUsers);
}
}
This function will return an array of users of each store.
I have answered according to my understanding of your question if any erros occur please reply below so i can fix if possible. I Hope this is what you wanted if not let me know.
UPDATE:
This is what i could understand from your request.
Store a , store b , store c has slug = xyz.
you have 50,000 users. 10,000 of them has slug xyz. and you need the information of those 10,000 users. if thats the case then the code below will help you out.
public function getStoreUsers(){
$slugtomatch = 'xyz';
$result;
$stores = Store::where('slug',$slugtomatch)->get();
foreach($stores as $store){
$users = $store->users;
$result = array($users);
}
return response()->json($result);
}
This will return an array of users those have the $slugtomatch value in their slug fields.
For example I have:
// Returns all projects
$projects = Projects::all();
To return categories, belonging to project, I use relationships and can do something like:
foreach($projects as $project) { ...show $project->categories... }
I need only specific projects, which are followed by specific user. On my projects_followers table I have user_id and project_id.
To retrieve projects which were followed I have this peace of code:
$projects = Project::rightJoin(DB::raw('(select * from projects_followers group by project_id) projects_followers'),'projects_followers.project_id','=','projects.id')->get();
// Note: This code doesn't include specifuc user_id.
It does retrieve specific rows, but the problem with this code is that laravel relationhips dont work on them. For example $project->categories return empty.
// Relationship
public function categories()
{
return $this->belongsToMany('App\Category');
}
How do I retrieve my model specific rows and make relationships to work?
Actually your question is:
How do I get projects liked/followed by Auth/Logged in User ?
Unfortunately you described it in such a way that it looks something else, anyways. Lets try to find the solution and for this I would like to use something like this:
$projects = Auth::user()->favorite_projects;
So how we can implement this to work, first of all the User Model should contain the method favoriteProjects so lets create it:
public function favoriteProjects()
{
return $this->belongsToMany(
'App\Project',
'projects_followers', // This table already exists as you mentioned
'user_id',
'project_id'
);
}
That's it. You will be able to load the projects followed by the current user and other relationship methods will work on every single project as well.
My workaround:
// I don't know how to create empty collection, so impossible conditions here.
$projects = Project::where('id', 0)->get();
$follows = DB::table('projects_followers')->where('follower_id', Auth::user()->id)->get();
foreach($follows as $follow) {
$project = Project::where('id', $follow->project_id)->first();
$projects = $projects->add($project);
}
I'm using Laravel to create a basic site with the following function: A user can follow certain topics. I have a 'users' table, a 'topics' table, and as a pivot table, I have a 'following' table.
users
----
user_id (primary)
user_first_name
etc..
following
---------
follow_id
user_id (foreign)
topic_id (foreign)
topics
------
topic_id (primary)
topic_name
etc...
I'm trying to create a page that displays all of the topics, but for the topics that the current user is following, I need to show an overlay on the box.
I have a User Model with the following function:
public function follows() {
return $this->belongsToMany('Topic', 'following', 'user_id', 'user_id');
}
However, I'm not too sure where to go from here (or whether this is right!)
Would be hugely grateful for any help.
First of all, you made a mistake on your follows method.
You have the same variable name on local and foreign id 'user_id'.
Then,
Did you already add a topic to an user ?
If yes, it would be great if you do the same as in your User model on the Topic model
public function followedBy()
{
return $this->belongsToMany('User', 'following', 'topic_id', 'user_'id');
}
From here, you can add a following topic to users by doing
$user->following()->attach($topic_id);
Or
$user->following()->attach([$first_topic, $second, $third, ...]);
You can use the sync method too, but that will delete all previous relationship between user and the topics which are not in the array.
To retrieve all information you can simply do the following:
foreach ($user->following as $topic) {};
/!\ Do not add parentheses to following otherwise you will get a QueryBuilder instead of a collection of the topics. /!\
If you want to add more filters (for example only active topics)
foreach ($user->following()->active()->get() as $topic) {}
Notice that here I added the parentheses which are necessaries because I do not directly want the topics but a QueryBuilder to filter the results.
Call the ->get() method when you are done filtering.
(This suppose you have a method called scopeActive() in your model)
See Laravel scope to do so : http://laravel.com/docs/eloquent#query-scopes
You can do the opposite on the topic side by doing :
foreach ($topic->followedBy as $user) {}
PS: sorry for my English, If you misunderstood something. Not my native language.
You sustain the following function in User Model
public function follows() {
return $this->belongsToMany('Topic', 'following');
}
and use below statement to retrieve the all topics of any user
$topics = User::find(1)->follows;
Where 1 is the user id for particular user.
1 In your setup you use non-default primary keys (topic_id / user_id / follow_id instead of id) so be sure to set:
protected $primaryKey = 'topic_id';
on each of your models accordingly.
2 I would suggest renaming the relation - follows is ambiguous, unless you have literally 3 models there.
3 Your relation for your current setup, like already suggested by #ChainList:
public function follows()
{
return $this->belongsToMany('Topic', 'following', 'user_id', 'topic_id');
}
4 In order to check if a user already follows given topic, do this:
// I Assume logged in user
$user = Auth::user();
$topics = Topic::all();
// somewhere in your view
#foreach ($topics as $topic)
{{ $topic->name }}
#if ($user->follows->contains($topic->id))
Already following this topic
#else
Follow this topic (put a link here or whatever)
#endif
#endforeach
With this you run just a single query for user's topics, when you call $user->follows for the first time.
My suggestion would be:
// leave id as primary key, it will make your life easier
// rename relation to
public function topics()
{
// rename table name to something meaningful
return $this->belongsToMany('Topic', 'topic_user'); // laravel convention
// or if you like topics_followers
}
Almost there, the follows() relationship needs to be like this:
public function follows() {
return $this->belongsToMany('Topic', 'following', 'user_id', 'topic_id');
}
Then you should be able to grab the topics associated to the current user by doing this:
$topicsUserIsFollowing = Auth::user()->follows;
To start following a topic, you can do this (assuming you have the topic's ID):
Auth::user()->follows()->attach($topic_id);
Edit
If you want to see if a topic is followed by someone, then in your Topic model put a function like this:
public function isFollowedBy($user)
{
return $user->follows->contains($this->topic_id);
}
So then you can do something like this:
$currentUser = Auth::user();
$topics = Topics::all();
foreach($topics as $topic) {
echo $topic->topic_name;
if( $topic->isFollowedBy($currentUser) ){
echo ' - [Already following this topic]';
} else {
echo ' - [Follow this topic]';
}
}
You'd want to put the loop in your view, this is just for illustration