Laravel 5.4 pagination with relationship - laravel

I have two tables questions and answers. Question table has relationship on answer table.
When paginating eloquent results on the first page it returns lets say 7 unanswered questions (with empty relationship) and 3 with answered questions, but I need it to return 5 with answers and 5 without answers in total 10.
Right now i'm doing this:
Question::with(['user', 'answers])->paginate(10);
Is there any way to return always 5 answered/5 unanswered instead of random?

The paginate() method returns a LengthAwarePaginator object so you can create your own as the doc suggests. Maybe (I haven't tested it) you can do it more or less like this:
$limit = $request->input('limit', 5);
$page = $request->input('page', 1);
$total = Question::count();
$offset = ($page - 1) * $limit;
$items1 = Question::with(['user', 'answers'])->has('answers')->limit($limit)->offset($offset)->get();
$items2 = Question::with(['user', 'answers'])->doesntHave('answers')->limit($limit)->offset($offset)->get();
$paginator = new \Illuminate\Pagination\LengthAwarePaginator(
$items1->concat(items2),
$total,
$limit,
$page,
['path' => $request->getPathInfo()]
);
return response()->json($paginator);

Related

Codeigniter Query binding multiple fields with the same value

I'm in a situation where I'm doing a MySQL query with Codeigniter and where I have a lot of fields value request which are ALL the same.
Example:
$this->db->query('SELECT * FROM abc WHERE user_id = ? AND msg_from = ? AND msg_to != ?', [$id, $id, $id]);
This has just 3 question marks but the query I'm working on is HUGE and has 19 question marks WHICH ARE ALL THE SAME variable.
So I was trying to figure out how to tell Codeigniter all question marks are pointing to the same variable without having to fill an array with 19 times the same variable.
I thought of a for-loop but I wanted to know if a shortcut exist.
you should be able to do this with Codeigniters Query Builder pretty easily
Something like that should work:
$this->db
->select('*')
->from('abc');
$arrFields = array('users_id', 'msg_from', 'msg_to');
foreach($arrFields AS $val)
{
$this->db->where($val, $id);
}
$query = $this->db->get();

How to improve code Laravel? [duplicate]

This question already has an answer here:
How to optimize code in Laravel?
(1 answer)
Closed 6 years ago.
I have the following code in Laravel, I get collection from request with a joined table translate.
That to get value from joined table I should use additional loop to format array which will be added to select list in blade template :
$arr = [];
$objectModel = new PlacesType();
$objectModel::$language = 2;
$subcategories = $objectModel::with("translate")->get();
foreach($subcategories as $key => $item){
$arr[$item->translate()->first()->objectId] = $item->translate()->first()->title;
}
return $arr;
So, how can I improve this code and escape this loop:
foreach($subcategories as $key => $item){
$arr[$item->translate()->first()->objectId] = $item->translate()->first()->title;
You could use mapWithKeys I guess?
https://laravel.com/docs/5.3/collections#method-mapwithkeys

Doctrine create function from another

I have the following function that counts the unanswered questions:
public function getUnansweredQuestions(Company $company){
$qb = $this->createQueryBuilder("q");
$andX = $qb->expr()->andX();
$andX->add($qb->expr()->isNull("q.answer"));
$andX->add("user.company = :company");
$qb->setParameter("company", $company);
$andX->add($qb->expr()->in("bid.status", ":status"));
$qb->setParameter("status", [PurchaseBid::STATUS_PUBLISHED, PurchaseBid::STATUS_CLOSED]);
$qb->leftJoin("q.purchaseBid", "bid");
$qb->leftJoin("bid.createdBy", "user");
$qb->where($andX);
return $qb->getQuery()->getResult();
}
I need to ask only if there is a question (answered or unanswered). I don't understand the code very well, but a way from this function should be exists.
See Count Rows in Doctrine QueryBuilder for solutions how to count number of rows using the Doctrine Query Builder. I guess this solves your problem. Count > 1 => you have questions.

Laravel 4 Paginantor::make, returning same data on every page

I have a set of documents, which I have stored in an array $resultset. I want to apply laravel Paginator::make method on it.
In Controller:
$total_resultset = count($resultset);
$perPage = 10;
$currentPage = Input::get('pageno',1);
$offSet = ($currentPage * $perPage) - $perPage;
$pagedData = array_slice($resultset, $offSet,$perPage, true);
$resultset = Paginator::make($pagedData, $total_resultset, $perPage);
and in view:
#foreach($resultset as $r)
$r->title
#endforeach
{{ $resultset->links() }}
The problem is, when I use $PagedData in Paginator::make it returns 10 docs per page. But all of the pages have same set of documents, rather than different docs, the page=2 does not show new set of docs. And when I use $resultset in Paginator::make it returns me all of the documents rather than only 10.
I can't use Eloquent or DB query as the $resultset has docs, based on different queries. I'm confused where I'm wrong.
P.S I've been trying to solve the issue since last two days, but didn't get successful. Please help me out, any kind of help would be appreciated.
Thanks in advance
$total_resultset = count($resultset);
$perPage = 10;
$currentPage = Input::get('pageno',0); //if you use default 1 you will skip 10 results
$offSet = ($currentPage * $perPage);// Ex: (1*10)= 10 - 10 = 0 you are not moving
$pagedData = array_slice($resultset, $offSet,$perPage, false);//maybe you are using Eloquent? you can use take() and skip() if is the case; and you was preserving the array keys in slice so never move really
$resultset = Paginator::make($pagedData, $total_resultset, $perPage);
hope helps :)

Manual paginator on merged collection

I have a merged collection I want to paginate and I can't seem to figure this out.
First off, the reason I need to create the paginator manually is because I fetch 2 collections first and merge them, like so:
$a = ModelA::all();
$b = ModelB::all();
$c = $a->merge($b);
Next step is to paginate this collection, I tried the Paginator and the LengthAwarePaginator
PAGINATOR
$page = 1;
$results = new Paginator($c, 2, $page);
Here I get the 2 first results in a paginator
$page = 2;
$results = new Paginator($c, 2, $page);
I still get the 2 first results, while i'd expect the third and fourth result (the collection is more then 2 elements long!)
LENGTHAWAREPAGINATOR
$page = 1;
$results = new LengthAwarePaginator($c, count($c), 2, $page);
Here I get a Paginator but the items contain all elements of the collection, no matter what page number i ask for (instead of the 2 i'm asking for)
Any ideas on what might be the problem?
Thank you in advance
According to the Laravel community this is intentional.
You should slice your items before passing it to the Paginator.

Resources