cakephp 3.4- Paginating belongsToMany associations - pagination

I have 3 Models.
Menus -> BelongsToMany -> Tags -> BelongsToMany -> Posts.
I am getting menu_slug as Input and I have to Paginate the Posts that are coming.
The query that I wrote is working as expected but I am not able to Paginate it according to Posts.
My query is:
$posts=$this->Menus->findByMenuSlug($slug)->contain(['Tags'=>function($query){
return $query->contain(['Posts'=>function($qry){
return $qry->select(['id','title','slug','short_description','created'])->where(['status'=>1,'is_deleted'=>2,'is_approved'=>1])->orderDesc('Posts.created');
}]);
}])->first();`
I don't have any Idea how to Implement this using Paginator. Please help.

Hi so after long search I figured out the solution. I don't know for sure if this is the best way to do this but it's working for now. If anybody has a better solution Please do provide that.
Solution that worked for me is:
$this->loadComponent('Paginator');
$this->Paginator->setConfig([
'limit'=>20
]);
$menu=$this->Menus->find()->where(['menu_slug'=>$slug])->contain(['Tags'])->first();
$tagIds=[];
if (!empty($menu->tags)){
foreach ($menu->tags as $tag) {
$tagIds[]=$tag->id;
}
}
$posts=[];
if (!empty($tagIds)){
$posts=$this->Posts->find()->contain(['Tags'=>function(Query $query)use($tagIds){
return $query->where(['Tags.id IN'=>$tagIds]);
}])->orderDesc('created');
$posts=$this->paginate($posts);
}
$this->set(compact('menu','posts'));`

Related

What is the use of "useMaster: true" in sequelize(nodejs)?

So I was going through a project codebase(nodejs 10) and they are using sequelize for executing queries in Mysql and at some places they are using useMaster: true.
I am just wondering what is it there for? Anyone having any idea?
Example code:
[error , coupons ] = await to(#wagner.get('sequelize').query( query , { useMaster: true, replacements : [coupon_offset,parseInt(limit)] ,type: #wagner.get('sequelize').QueryTypes.SELECT } ))
Didi you check the official documentation?
It says about useMaster in the Params section of query instance method:
Force the query to use the write pool, regardless of the query type.
See query method
I'm not sure if it's applicable to MySQL but still I'd recommend to find out more about write pools.

SwiftUI, Xcode 13, Question about .filter'ing CoreData

#FetchRequest(
entity: Client.entity(),
sortDescriptors: [])
private var clients: FetchedResults<Client>
(...)
var searchResults: FetchedResults<Client> {
if searchText.isEmpty {
return clients
} else {
return clients.filter({$0.name!.contains(searchText)}) // Error here!
}
}
(...)
ForEach(searchResults, id: \.self) { client in
(...)
Error
Cannot convert return expression of type '[FetchedResults<Client>.Element]' (aka 'Array<Client>') to return type 'FetchedResults<Client>'
Hi,
I'm not sure how my logic is wrong. Could someone please tell me how to fix searchResults?
Also, is this the more efficient way to filter results or should I filter in the ForEach()? It seems pretty slow when I put the filter in ForEach()
While I know you have a code fix, and it is the correct one, I wanted to answer the question for posterity as I have run into this myself. The logic is wrong simply because your searchResults var is of type FetchedResults<Client>, but a filter returns an Array. So, the error message is telling you exactly the problem. You are trying to return an [Client] as a FetchedResults<Client> so you have a type mismatch.
You have two solutions:
You can filter in the fetch request, which is how you solved it per #Larme suggestion. This is especially helpful if you only need the filtered results in the UI and/or you have a lot of results.
You can filter when you use your fetched results. This is useful when you want your user to be able to determine what is filtered out by their own selections, but you don't know what filtering they will want ahead of time or that regardless of the filtering you are doing, you may need the whole FetchRequest later.

Laravel search for title and related tags

I want to search for posts by title and the related tags, which have a many-to-many relationship with posts. I came pretty far but theres something that botheres me. Here is my code:
$searchInput = Input::get('search');
$posts = Post::join('post_tag', 'post_tag.post_id','=','post.id')
->join('tag','tag.id','=','post_tag.tag_id')
->where('post.title', 'LIKE', '%' . $searchInput . '%')
->orWhere('tag.title', 'LIKE', '%' . $searchInput . '%')
->orderBy('post.created_at', 'desc')
->groupBy('post.id')
->with('tags')
->paginate(8);
This code (kind of) works. Lets say I have a post with the title This is a test subject and with the tags CSS and HTML.
When I search for test or subject, I find the post, no problems here.
When I search for CSS or HTML, I find the post, no problems here.
When I search for a combination of the two above (for example when I search for test and CSS, I find no post. Also, when I search for CSS HTML I don't get any results.
I hope somebody could help me out optimizing this search query, it gives me a headache.
I've found the answer, this might be usefull for others. Here is the code:
$posts = Post::join('post_tag', 'post_tag.post_id','=','post.id')
->join('tag','tag.id','=','post_tag.tag_id')
->where('post.title', 'LIKE', '%' . $searchInput . '%')
->orWhereIn('tag.title', preg_split('/\s+/', trim($input['query']))) //The fix
->orderBy('post.created_at', 'desc')
->groupBy('post.id')
->with('tags')
->paginate(8);
There are multiple tags, the fix is to trim them and put them in an array. Then simply change orWhere() to orWhereIn().
I would try a query scope. And then use your relationships to query the rest...
class Post extends Eloquent {
public function tags()
{
return $this->belongsToMany('Tag');
}
public function scopeTitle($query, $title)
{
return $query->with('title', '=', $title);
}
}
Then you could use the Model like this:
Post::title('Post Title')->tags();
This would get the post by the title and then all the tags associated with it if your Many To Many relationship is setup properly.

Kohana/ORM - Assign relations to views

I have an object in a controller's method:
$post = ORM::factory('post', array('slug' => $slug);
that is sent to the view:
$this->template->content = View::factory('view')->bind('post', $post);
I've created 1-n relation between post and comments. So good so far.
The main issue is: how should I pass post comments to the view? Currently I'm getting them in the view ($post->comments->find_all()) but I don't feel it's the best method (and not matching MVC standards in my humble opinion). I was also thinking about assigning them to the property in the controller ($post->comments) however I get an error about undefined property (which makes sense to me).
How would you recommend to solve that issue?
Why not grab the comments in the controller and pass them to the view for presentation? At least that's how I'd go about this.
$post = ORM::factory('post', array('slug' => $slug));
$comments = $post->comments->find_all();
$this->template->content = View::factory('view')->bind('comments', $comments);
In regards to your multiple pages comment, which I assume you mean posts...
This is what I would usually do.
$posts = ORM::factory('post', array('slug' => $slug))->find_all();
$view = new View('view');
foreach ($posts as $post) {
$view->comments = $post->comments;
$this->template->content .= $view->render();
}
Though this may not be the most resource friendly way to accomplish this, especially if you're working with many posts. So passing the posts to the view and then doing the foreach loop inside the view may be a better way to go about this.
$posts = ORM::factory('post', array('slug' => $slug))->find_all();
$this->template->content = View::factory('view')->bind('posts', $posts);
Though I also don't necessarily think running a select query from the view is the worst thing in the world. Though I'm no expert... ;)
I had asked this question a while ago in regards to CodeIgniter... passing an Array to the view and looping through it seemed to be the favored response...
Using CodeIgniter is it bad practice to load a view in a loop

Get all deleted record

I'm looking for a way to get all records where deleted is set to true on a particular table. How might I accomplish this?
Note: Using auto-generated class by SubSonic. Not T-SQL.
The auto-generated SubSonic classes don't support querying logical deletes. But you can do this (version 2.1/2.2 syntax):
public partial class TableClassCollection
{
public TableClassCollection LoadAll(bool suppressLogicalDeletes)
{
SubSonic.SqlQuery q = new SubSonic.Select(TableClass.Schema)
.From(TableClass.Schema);
if (suppressLogicalDeletes)
{
q.Where(TableClass.DeletedColumn).IsEqualTo(false);
}
return q.ExecuteAsCollection<TableClassCollection>();
}
}
More examples at subsonicproject.com
I've never heard of SubSonic before, but a quick Google search turned up: Select Queries in SubSonic.
So, using that page as a guide, it sounds like you'd be able to write your query as:
FooCollection deletedFoos = // use the generated collection class
DB.Select().From("FooTable") // table name goes here
.Where("deleted").IsEqualTo(true) // might need 1, depends on database?
.ExecuteAsCollection<FooCollection>(); // should match the type above
not a lot of detail in your question, but assuming there's a column named "deleted," it would look something like this:
select * from tableName where deleted = true

Resources