I'm trying to find a number of UserComment using a viaTable on the table called user_comment_user in Yii2. However I can't seem to get my variables/query inserted properly.
Currently I've got two queries set up, to check if (on their own) they achieve the correct result, which they do.
These are the two queries that somehow have to be merged into one:
public function findConversation($id)
{
$query = $this->hasMany(UserComment::classname(), ['id'=>'user_comment_id'])
->viaTable('user_comment_user', ['sender_id'=>'id'], function ($query) use ($id) {
$query->andWhere(['receiver_id'=>$id]);
});
$query2 = $this->hasMany(UserComment::classname(), ['id'=>'user_comment_id'])
->viaTable('user_comment_user', ['receiver_id'=>'id'], function ($query) use ($id) {
$query->andWhere(['sender_id'=>$id]);
});
return $query;
}
The answer was actually much simpler than I had imagined:
public function findConversation($id)
{
$query = UserComment::find();
$query->leftJoin('user_comment_user', 'user_comment_user.user_comment_id=user_comment.id');
$query->where(['receiver_id'=>$this->id, 'sender_id'=>$id]);
$query->orWhere(['receiver_id'=>$id, 'sender_id'=>$this->id]);
$query->orderBy(['created_at'=>SORT_DESC]);
return $query;
}
Related
Quick question, I have Model that related to different model (one to many).
I'm building method that should return js array with related table included to array.
But I need to sort a bit warrant_grants, I need to return $warrant_grants->where('status', active). So My ->where() doesn't work this way:
public function warrants($company_id){
$company = auth()->user()->companies()->findOrFail($company_id);
$warrants = $company->warrants;
foreach($warrants as $warrant) {
//this doesn't work
$warrant->warrantGrants->where('status', 'active');
}
$warrants = $warrants->toArray();
return array_splice($warrants, 0);
}
Relationship:
public function warrantGrants()
{
return $this->hasMany(WarrantGrant::class);
}
Need this little help, bc it returns me data with any status, I need only 'active'
Try this
$company = App\Company::whereHas('warrants.warrantGrants', function ($query) {
$query->where('status', '=', 'active');
})->get();
I have one similar (area) value in two tables one and two and these two tables has relation with main table master. At a time, the master table will be having data in one relation only and the other one will be null.
With this architecture, I have a search page where user can search any values related to these tables and the search fields are placed with AND condition.
Here, if user enters some value for area I need to check the area value exists in any one of the tables (one or two) without breaking the AND condition. Tried the below code but it is breaking AND rule and considering OR. Any suggestions to fix?
$result = Master::where(function ($query) use ($request) {
if ($request->filter == true) {
$query->where('user_id', Auth::user()->id);
}
// other conditions here
if (!empty($request->area_from) && !empty($request->area_to)) {
$query->whereHas('one', function ($query) use ($request) {
$query->whereBetween('area', [$request->area_from, $request->area_to]);
});
$query->orWhereHas('two', function ($query) use ($request) {
$query->whereBetween('area', [$request->area_from, $request->area_to]);
});
}
// other conditions here
})->with(['one', 'two'])->paginate($request->item);
You are wrapping all of your where statements in brackets. I think what you want to do is pull your first part of the query out of the where clause so that you can easily wrap the whereHas part in brackets.
// Initialise the model
$query = new Master;
// Start building the query
if ($request->filter == true) {
$query->where('user_id', Auth::user()->id);
}
if (!empty($request->area_from) && !empty($request->area_to)) {
// Wrap these in brackets so we don't interfare with the previous where
$query->where(function($query2) use ($request) {
$query2->whereHas('one', function ($query3) use ($request) {
$query3->whereBetween('area', [$request->area_from, $request->area_to]);
});
$query2->orWhereHas('two', function ($query3) use ($request) {
$query3->whereBetween('area', [$request->area_from, $request->area_to]);
});
}
}
$query->with(['one', 'two'])->paginate($request->item);
You can create a merged relationship refer this link
public function mergedOneAndTwo($value)
{
// There two calls return collections
// as defined in relations.
$onedata= $this->one;
$twodata= $this->two;
// Merge collections and return single collection.
return $onedata->merge($twodata);
}
and use whereHas('mergedOneAndTwo')
Using a closer where and making the conditional inside may work fine
$master = Master::with('one')->with('two');
$result = $master->where(function($subQuery)
{
$subQuery->whereHas('one', function ( $query ) {
$query->whereBetween('area', [$request->area_from, $request->area_to] ); //assuming $request->area_from, $request->area_to is range of value
})
->orWhereHas('two', function ( $query ) {
$query->whereBetween('area', [$request->area_from, $request->area_to] );
});
});
I tried to fetch data using joins and the data is repeating,
The controller code is:
public function searchjobs2()
{
//$id=$_SESSION['id'];
$lan = $_POST["picke"]; //var_dump($id);die();
$value['list']=$this->Free_model->get_jobs($lan);//var_dump($value);die();
$this->load->view('free/header');
$this->load->view('free/searchjobs2',$value);
}
And the model:
public function get_jobs($lan)
{
$this->db->select('*');
$this->db->from("tbl_work_stats");
$this->db->join("tbl_work", "tbl_work.login_id = tbl_work_stats.login_id",'inner');
$this->db->where("language LIKE '%$lan%'");
// $this->db->where('tbl_work_stats.login_id',$id);
$this->db->order_by('insertdate','asc');
$query=$this->db->get()->result_array();//var_dump($query);die();
return $query;
}
I have used
foreach ($list as $row){
...
}
for listing.
Using distinct will remove duplicate fields:
$this->db->distinct();
From what I can see, your query has ambiguity, and an error in the join statement, also your where like is part of the problem, I would recommend trying this even do there are some missing info, find out wich field you need to join from the second table.
public function get_jobs($lan){
$this->db->select("tbl_work_stats.*, tbl_work.fields");
$this->db->from("tbl_work_stats");
$this->db->join("tbl_work", "tbl_work_stats.login_id = tbl_work.login_id","inner");
$this->db->where("tbl_work.language LIKE", "%" . $lan . "%" );
$this->db->order_by("tbl_work_stats.insertdate","asc");
$query=$this->db->get()->result_array();
return $query;}
do you mean to join on login_id?
I am guessing that is the user logging in and it is the same for many entries of tbl_work_stats and tbl_work.
you didn't post your schema, , but login_id doesn't seem like right thing to join on. how about something like tbl_work.id = tbl_work_stats.tbl_work_id or similar?
also CI $db returns self, so you can do:
public function get_jobs(string $lan):array
{
return $this->db->select()
->from('tbl_work_stats')
->join('tbl_work','tbl_work.id = tbl_work_stats.work_id')
->like('language',$lan)
->order_by('insertdate')
->get()
->result_array();
}
I have some problem with a query in Laravel.
I want to create a filter query by column in server table but I don't know how to do this.
Need help to modify the following line:
$data = $video->files()->with('server')->get();
Model: server
public function files()
{
return $this->hasMany('App\Models\File', 'id', 'server_id');
}
Model: file
public function server()
{
return $this->belongsTo('App\Models\Server', 'server_id', 'id')->ordered();
}
My current query return this:
(but it returned all, I need return only FILE flitered by type = 6 which is server table) I don;t know how to do this. On screen below data about type server is on #relations array
Use WhereHas. Takes the relation name and a closure as a parameter, where you can define sub query like functionality with the relation.
$data = $video->files()->with('server')->whereHas('server', function ($query)
{
$query->where('type', '6');
})->get();
how can I sort the return data from a query using whereHas? In my query i have to get the users data which id exist on interest table but i need to sort it using the datetime column from interest. But, the return query do not sort the data at all.
Here's my code snippets in case it would help you understand my problem.
Model (name: User)
//***relationship***//
public function interest(){
return $this->belongsTo('Interest','id','interest_by');
}
Controller
$userInterested = User::whereHas('interest',function($q) use ($id) {
return $q->where('interest_on', $id)
->orderBy('datetime');
});
$userQuery = $userInterested->get();
return $userQuery;
remove return from where has and try this.like
$userInterested = User::whereHas('interest',function($q) use ($id) {
$q->where('interest_on', $id)
->orderBy('datetime');
})->get();
return $userInterested;
$userInterested = User::whereHas('interest',function($q) use ($id) {
return $q->where('interest_on', $id);
})->orderBy('datetime');
$userQuery = $userInterested->get();
return $userQuery;