I am using Laravel with Voyager for the back-end.
I made a relationship between Posts model and Categories model.
When adding a new Post, I can choose an according category using a dropdown.
How can I make this dropdown show Categories according to certain conditions? (Let's say, only subcategories)
You can easily filter the shown relationship options by defining a local scope in the foreign model. For example, if you want to only show active entries of categories in a relationship input, create a scope as given in your Category model,
public function scopeSubcategories($query){
return $query->where('parent_id', '!=' , null);
}
Now, go to the BREAD builder and add the following to the relationship options
{
"scope": "subcategories"
}
The value is the name of your scope-method without the word scope.
The value for scopeSubcategories() is subcategories.
Related
how do we add a limit to many-to-many relation. Following the example in the documentation let's say we have 3 tables post, category and post_category. Let's say I have a list of posts and on every post a possibility to choose a category.
How can I 'limit' the relation so that there can't be more then 5 categories per post and 100 posts per category?
I have managed to do so using a checking if count(post->books) < 5 on the create action of post_category controller but am looking for a way to do it more Yii friendly, if that exists.
Working on Yii 1.1.14.
You can using custom validation rules. For example in your PostCategory model, add the following rule
public function rules()
{
return [
[['post'], 'validateSize'],
];
}
Then anywhere in the model add validateSize()
public function validateSize($attribute_name,$params){
if(sizeof($this->post->categories) > 4)
$this->addError($attribute_name, Yii::t('post', 'You cant have more than 5 categories per post'));
}
This will give an error when trying to create a new category belonging to a post that already has 4 categories
This is a weird implementation that I am trying to do in eloquent.
So the concept here is:
I am trying to create a dynamic relation for a product and product instance.
Category has multiple products. Products have multiple types. I decided to create multiple product types depending on what the product is for.
For eg: There can be Food and Clothes. Food is a different class and has properties totally different for it. There are other things that I need to differentiate for food and clothes.
I obviously have two different tables for these but a single category table that has product type slug to differentiate which category is for which product.
There is a Product class that has general description, slugs etc. everything that a general product has. The Food and the Clothes class are for instance of these products with specific details for the particular instance
I have defined relation of product and product instance like this.
function instance( $productInstance ) {
return $this->hasMany( get_class( $productInstance) );
}
I can get relation like this. $product->instance( $instance )->get();, gives me the exact relation that I need, based on what class instance I pass in the relation.
This worked very smoothly. Until I needed to load multiple relations
This is where I am stuck.
I cannot pass the the model in the instance in with function to eager load or load function to lazy load relation. This function does not work as relation
$category->with(['subCategory.products' => function( $q ) use ($productModel ) {
$q->with( 'instance' );
}])->get();
I cannot pass the instanceModel class to tell the relation what table to fetch from.
Is there a way that I can pass the modelInstance so that I can get the two level relation loaded into subCategory
Or a different implementation of this?
Any Suggestions??
I am currently using Laravel (PHP framework) in order to construct an ecommerce site.
The site will have a lot of categories(for products) of which there is ruffly 100-150 and will probably be more as there will be a backend site to add more.
Some times it will be necessary for a category to appear in more than 1 parent category on the site.
Category Relationships I am trying to achieve:
A category can have many child categories.
A category may have more than one parent category.
I am very confused as to how to set up the second of these two relationships correctly within Laravel.
So my question is:
How do I set up a database structure and Model relations so that a category can belong to many other category without any duplication in the categories table.
I would like to know what tables/columns I need and also what types of relationships need to be set in the models please.
This model seems to work:
I have a table called category_category and relation:
public function parentCategories()
{
return $this->belongsToMany('TottonTimber\Category', 'category_category', 'category_id', 'parent_id');
}
public function childCategories()
{
return $this->belongsToMany('TottonTimber\Category', 'category_category', 'parent_id', 'category_id');
}
Yet this doesn't seem like the correct way of doing it as both are "belongsTo"
In Many to Many to relations. Both models do have a belongs to relation with the other. For example in classic User & Roles Scenerio, User Belongs to Many Roles & Roles Belongs to Many Users.. So as you see 'Belongs to' relationship both sides. Here as you have same model for both ends of your relations, you have to put 'belongsto' for both your relation definations. That is perfectly ok it seems.
I'm trying to get my head around using polymorphic relationships for a many-to-many relationship between suppliers and products:
products
id
name
suppliers
id
name
product_supplier
id
product_id // belongsToMany easily takes care of this id
supplier_id // and this id
price // this can be fetched using withPivot('price')
deliverymethod_id // I'm having difficulties "joining" this one.
I'm confident in using belongsToMany(), I can easily do something like this:
public function products()
{
return $this
->belongsToMany('Supplier')
->withPivot('price');
}
But the catch here is joining to that third column in the relationship table:
deliverymethods
id
name
I am unsure how to do this. I've been told that Polymorphic Relationships are what I'm after however I'm unsure how to implement them for my situation.
http://laravel.com/docs/4.2/eloquent#many-to-many-polymorphic-relations
According to the documentation, I would have to rename my table columns to include *able_id and *able_type. This is really confusing.
I was expecting laravel to having something like belongsToMany('Supplier')->withAlso('Deliverymethod')
I'm afraid that method does not exist (yet?).
What I fall back to is manually filling in the 3rd relation:
public function products()
{
return $this
->belongsToMany('Supplier')
->withPivot('price', 'delivermethod_id');
}
Now I can access ->pivot->deliverymethod_id on every Product that I get via Supplier.
You could even add a function in your Product model that fills this in automatically:
Class Product ... {
protected $appends = array('deliverymethod');
public function getDeliverymethodAttribute()
{
return Deliverymethod::find($this->pivot->delivermethod_id);
}
Now every time you request a product via it's relation to the supplier, it automatically includes a deliverymethod attribute with the object in it.
(To have it not throw an error when you get a Product directly, just remove the $appends variable from the Product model and call the getDeliverymethodAttribute() method manually whenever you need it.)
Short explanation about polymorphic relations:
Polymorphic relations are for relations, where two models are related to a third model at the same time. So for example both a User and a Product can have a Picture of them. Now, it doesn't make sense to have two models for the pictures (UserPicture and ProductPicture), since they both have the same characteristics. This would be a perfect reason to use a polymorphic relation, where the Picture can both belong to a User or a Product.
However, in your case the Deliverymethod applies directly to the relation between Supplier and Product. So this is not where polymorphic relations would work, but it has instead to be done the way you did it.
Currently i'm having a problem. I want to access the data available in the 4th table of my DB.
Db image:
I have the tables in this way: Categories --> Categories_Companies --> Companies --> Affiliates
Like it shows in the image i'm on the categories and in the Categories view (views/categories/view.ctp) i want to show the fields title and url from the affiliates table.
There is another way of doing that without using the this->query?
Regards
You access a table through its model. The Category model is automatically included in the CategoriesController by naming convention. You can include other models by using $uses.
var $uses = array('Category', 'Affiliate');
function view() {
$this->Category->find(…);
$this->Affiliate->find(…);
}
Or, if your models are linked through associations, you can access them through an association:
$this->Category->Company->Affiliate->find(…);
Both examples are equivalent, the first is just more convenient.