Ordered Many-Many Relationship in Doctrine? - sorting

Attempting to link Categories to Websites, using WebsiteCategory as the refClass.
WebsiteCategory has a column rank, which indicates the order in which the categories should be retrieved when you call $website->getCategories()
I'm stumped, didn't think this would be so difficult. Can anyone help?

Was not able to get doctrine to order the relationship natively (like Damien was suggesting) instead, added a getCategories() function to the model which runs the proper query and returns the result set.

This is not supported for Many to Many relationships, the bug report is linked below with a possible patch, although some comments indicate it was not working. As already noted by OP, I think the solution is to override the getCategories() function.
http://www.doctrine-project.org/jira/browse/DC-651

You can add an orderBy param in your schema.yml:
Gallery:
columns:
title: string(255)
relations:
Images:
local: id
foreign: gallery_id
foreignAlias: Gallery
type: many
orderBy: position DESC
You can put multi fields with a comma.

Related

Inverse of belongsToMany

I got two Models:
Order
Invoice
Each Order can have many Invoices - and an Invoice can belong to many Orders.
So I can search for an Order and check: "Hey, which Invoices have been created for this Order?"
The other way round each Invoice can belong to multiple Orders, because maybe a customer ordered two products on the same day and so it would be great he'd only get one Invoice, which includes both orders.
So this is how I did this:
Invoice
public function orders()
{
return $this->belongsToMany(Order::class);
}
Order
public function invoices()
{
return $this->belongsToMany(Invoice::class, 'invoice_order');
}
This does work - but it does not seem right to change the table to the intermediate table invoice_order here. Do you have any thoughts on this? :-)
Thanks in advance for your thoughts :-)
Seperating the relation into a seperate pivot table is the commonly used method in laravel (and in most other frameworks) for many to many relationships.
It's easy to maintain, easy to get related models using many to many relationship, and if someone else needs to work on it in the future, they'll probably have used it in the past as well so wouldn't end up burning their heads.
The other method you could use is to create a json column on one of the tables (you can create on both tables as well if you want, but that's just extra overhead). Then you can store the ids of the related models in this json column. You can then join the tables using the json related commands provided by your database. Eloquent does not support relationships on json, but you can use this package staudenmeir/eloquent-json-relations to build relationships on json fields.
So overall, I'd suggest keeping a pivot table like the standard way, but if that just won't do, then you can try the json column method

How to list related blog posts in OctoberCMS

I am building an App with OctoberCMS and wanted to list related blog posts at the bottom of each post page basing on categories. I figured out rainlab_blog_posts table does not have a foreign key pointing to blog categories table. To achieve what wanted I thought of extending the blog_posts table and added category_id as foreign key using a plugin. I defined foreign key constraints in table migration. Everthing seem to be fine. My challenge is, How can I insert category id in posts table each time a new post is created. OctoberCMS create post backend has an option where the author assigns a category to a new blog post by selecting from list. Just don't understand how to pass this category id and insert into rainlab_blog_posts table in category_id field.
This is what I want to achieve in my API:
routes.php
use Rainlab\Blog\Models\Post;
Route::get('apiv1/related-posts/{postid}',function($id)
{
$post = Post::where('id',$id)->first();
$posts = Post::where('category_id',$post->category_id)
->where('id','!=',$id)
->orderBy('views','desc')
->get()->take(5);
return $posts;
});
Or if there is a better way of achieving this will appreciate. Cheers!
Hmm seems something wrong here,
As first I can see from Blog Plugin that Blog <=> Category it is MM relation so you will not find category_id in rainlab_blog_posts table as all relation is maintained by this mm-relation table rainlab_blog_posts_categories.
So I think you will select only one category for blog so you can get related blogs for only that category. [ assuming from your code and description ]
we can utilize relationships for that.
So your code can look like this
use Rainlab\Blog\Models\Post;
Route::get('apiv1/related-posts/{postid}', function($id)
{
$post = Post::where('id',$id)->first();
// we need this because there will be mm relation so
// we fetch first category and this will be based on
// [ name sorting - does not matter as there will be only one cat. ]
$firstCategory = $post->categories()->first();
// now we fetch only that post which are related to that category
// but we skip current post and sort them and pick 5 posts
$posts = $firstCategory->posts()
->where('id', '!=', $id)
->orderBy('views','desc')
->limit(5) // use limit instead of take()
->get();
// use limit instead of take() as we don't need extra data so
// just put limit in sql rather fetching it from db then
// putting limit by code - limit() is more optimised way
return $posts;
});
Good thing now you don't need to add that category_id field on rainlab_blog_posts. So, I guess now you Also don't need to worry about adding it during post insertion.
if any doubts please comment.
Incase you simply want to display related blog posts without having to customize the blog database, there is an OctoberCMS plugin called Related Articles
that requires rainlab blog plugin. It will display all the other articles belonging to the post's category.
On your Backend menu, go to settings,on System, go to Updates and Plugins.
Go to Install plugins. Search for plugin Related articles. The creator is Tallpro. Install it.
Go to CMS. On the page you want related articles, go to components and drag Related articles. Save and preview it. You can also fork the component to edit how you want your related articles to be displayed. You will find more information on the documentation.
If you encounter any problems feel free to inquire or you can check out the plugin reviews for problems faced and their solution.

How to join two belongsToMany objects

I am trying to represent friendships in my Laravel project database.
I have created a table profile which contains all user-data.
A second table profile_profile with the columns profile_id and friend_id.
With that I am able to get persons wo wants to be friend with me:
$this->belongsToMany('App\Profile', 'profile_profile', 'friend_id', 'friend_id');
an friends I am want to be befriendet:
$this->belongsToMany('App\Profile', 'profile_profile', 'profile_id', 'friend_id');
But in the end you are only friends if both want that so. So I tried to combined them but join or something similar didn't work.
I did a research on this platform and google over 2 hours. I am afraid that my skills are to limited, but I really like to ask for help.
Thank you in advance.
Quick solution: add another column in the profile_profile table, say, "accepted" as boolean and default to FALSE.
When a user accepts a friend's request, toggle the "accepted" field to TRUE.
Then you could search like $profile->profiles()->wherePivot('accepted', true)->get()

How can I return Many to One relation data joined with One to One data?

I have a question concerning Laravel schema.
Was that a bad idea to create an additional one-to-one table user_description, to store additional user data? Here is my schema:
For example now I don't know how to use eager loading to get user_photos if at first I retrieve topics' data.
Here is the code I use to get the last topics with user data:
return Topic::with('blog', 'user')->orderBy('topics.id', 'DESC')->get();
assuming your User-Model has a relation description() I suppose this does what you want.
return Topic::with('blog', 'user', 'user.description')->orderBy('topics.id', 'DESC')->get();
the concept is called sth. like eager loading of nested-relationships and is documented at the bottom of the eager loading documentation of laravel

laravel eloquent get related articles based on a tag

I'm a bit confused about how to do the following.
I have a table of articles and a table of tags with a many to many join and a pivot table between the two. I've got the relationships set up in the models
An articles can have more than one tag.
How can I easily(?) obtain a list of related articles for an article based on the tags attached to the current article.
I've tried querying from the tags side as follows:
foreach($article->tags()->get() as $tag) {
$relatedArticles .= Tag::with('articles')
->where('id','=', $tag->id)
->take(6)
->get();
}
This produces a nil response
I'm not sure about how to query from the articles to find articles with the tags dynamically.
So if an article has attached tag1 and tag2 I then want to retrieve all articles which have either tag1 or tag2 attached to them (ideally sorted on article date). The tags will be different for each article and may just be one or many.
Ideally i'd like to do this with an eloquent query but not essential - I'm not sure how to do in mysql either as a starting point.
Any help appreciated
Provided you are using Laravel 4.1, you can do something like this using the whereHas eloquent method:
$tag_ids = $article->tags()->lists('id');
$relatedArticles = Article::whereHas('tags', function($q) use ($tag_ids) {
$q->whereIn('id', $tag_ids);
})
->orderBy('created_at')
->take(6)
->get();
Breakdown
There's a few things going on here:
lists()
You can use the lists method on a select to get just a particular column, we're only concerned with the ID column in this case.
More info here: http://laravel.com/docs/queries#selects
whereHas()
We're using the new whereHas method which you can read.
More more about here: http://laravel.com/docs/eloquent#querying-relations
use()
Since the whereHas method accepts a closure (or 'anonymous function'), the function doesn't have any access to variables set externally, so we need to send them through to the function. We can do this with use.
More information here: http://www.php.net/manual/en/functions.anonymous.php

Resources