Using Other Column as Identifier in Polymorphic Relationship - php

I am using Eloquent on my project and I am currently facing a problem with regards to polymorphic relations. What I would like to do is to specify another column instead of the primary key in morphing relationship such that:
Products
id
product_number
description
User
id
username
Photos
id
path
imageable_id
imageable_type
In this scenario, I would like to create a relation with both the products and the users table, but in the product relationship, instead of putting the ID as the relationship identifier, I would like to put the product_number because of some reasons. Is it possible as of version 5.1?
Thanks,
Jan

It is possible by specifying the local key like so:
return $this->morphMany('App\Photos', 'imageable', null, null, 'product_number' );

Related

Laravel Eloquent - How to define such a relationship: Comment::language()->name

The languages table has: id, shortcode
The comments table has id, user_id, comment, language_id (foreign key)
In the Comment Model I defined Language as a hasOne Relationship
In the Language Model I defined Comments as a hasMany Relationship (this is wrong?).
In Tinker I get this error when I try to execute: $comment->language()->get():
Column not found: 1054 Unknown column 'languages.comment_id' in 'where clause' (SQL: select * from `languages` where `languages`.`comment_id` = 7 and `languages`.`comment_id` is not null)'
Why is Laravel searching in the languages table for the comment_id? It seems I misunderstand something completely.
What is the right way to do get the language shortcode? I thought $comment->language()->shortcode should work.
And what is the most efficient way to preload all the language_id and shortcode information without performing duplicate queries since this is used a lot?
Laravel makes assumptions on your key-names in your relationship. Because you use the hasOne relationship, Laravel expects the key to be in the languages table, named comment_id.
Your Comment model should use a belongsTo relationship to Language and drop the hasOne. This way laravel makes the assumption that the foreign-key is actually in the comments table, named language_id, which is the case :).
Using the belongsTo relationship solved the problem.
Afterwards I could access it with $comment->language->shortcode;
thanks everyone!

Laravel 4.2 ORM - Querying relation with various tables in between

I have a database schema that goes like this:
Section
id
name
Subsection
id
name
section_id
Category
id
name
subsection_id
SubCategory
id
name
category_id
Product
id
name
subcategory_id
As you can see, each table has a foreign key that references the previous table. The problem comes when I try to get, for example, the Section from the current product or get all products from one section. So far I have tried this:
Section::with('product')->find(1)->product;
But I get this:
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'product.section_id' in 'where clause' (SQL: select *
from products where products.section_id in
(1))
1 - This makes me think I need to set up a section_id in the products table to make this work. Is this correct?
2 - Shouldn't the Laravel ORM automatically go up the table hierarchy from Product to Section and get the results?
3 - Is there a way to do this maintaining my current table structure, I mean, without adding extra fields in the tables for the foreign keys?
Thanks.
No that is one way to do it but it isn't the only way.
No, how would it know that automatically?
I believe so and you can always create a specific query when laravel relationships don't work for you.
Okay first this assumes you have relationships setup on all the models to access the one below it. If that isn't the case you will need to setup the relationships.
Section::with('subsection.category.subcategory.product')->get();
I've never tried such extreme nesting but I believe this will work. The Laravel Docs talk about eager loading and scroll to see the nested example.
Another item that comes to mind is the hasManyThrough relationship. You couldn't do it for this number deep but it may be something you want to look into.
A brief summary from the docs is taking the first three from your example, Section, Subsection, and Category and then in the section class you would have this relationship.
public function category()
{
return $this->hasManyThrough('Category', 'SubSection');
}
The laravel docs with more information.

How to create relations in YII for 3 DB tables

I have 3 DB tables tbl_categories, tbl_items, tbl_items_categories like this:
tbl_categories fields: id (category id - primary key), name (category's name)
tbl_items fields: id (item id - primary key), name (item name)
tbl_items_categories fields: id (primary key), item_id (id field value from tbl_items), category_id (id field value from tbl_category)
Please note that one item can be in multiple categories (tbl_items_categories is being used for this purpose)
I have created 3 models (in YII) - categories, items, itemMultiCategories for these tables.
Can anyone please let me know how to create relations in YII for following purpose:
If I have an item id, I should be able to get all its category names (good to have category ids)
If I have category id, I should get all item names in that category (good to have item ids as well)
Thanks in advance.
You are not creating relations in Yii, you are doing it in the database.
Take a look at this answer.
After you created the relations, go into the gii (http://yourhost.com/?r=gii), and create all the models again. Don't forget to check the checkbox for relation creation.
What you have here is a many to many relationship bridged by an associative table (tbl_items_categories). This should be easily handled by Yii's many to many relational active record.
http://www.yiiframework.com/doc/guide/1.1/en/database.arr
For instance, to have a relationship in your items model that gets you all categories, you could do something like this:
public function relations()
{
return array(
'categories' => array(self::MANY_MANY, 'categories','tbl_items_categories(item_id, category_id)'),
);
}
The foreign key, tbl_items_categories(item_id, category_id), is just the name of your associative table with the table fields that will match your linked tables, in parentheses. Your fields should be listed in order, such that the field that will link to the primary key of the current model is listed first. My understanding is if you want to get items by category, the foreign key in the relationship in your category model will look like this: tbl_items_categories(category_id, item_id).
A note on your associative table:
You might consider removing the "id" field, since the combination of item_id and category_id is probably unique. Also, because the table only needs to be referenced in these relationship declarations, you probably don't need to set up a separate model for it.

Resolving many to many relationship MYSQL database

I have 3 tables,
users(id) , userproduct (user_id,product_id) and product (id).
When a user adds a product their user_id and the product_id is saved in USERPRODUCT table.
Now at the same time another user can save a product (kind of like "set as favorite") for this I need to save the user_id of the user who saved it and the product_id of the product. This will create another table (call it favorites) however this table is also a resolve to the many to many relationship between "users" table and "product" table.
the question: is it possible for this, to have 2 tables resolving a many to many relationship or is there any other way to solve my issue.
if it is possible how will one be draw this in the ER diagram
it depends on what you want.
you may use only one table and design your relations with boolean fields
USERS(id)
PRODUCTS(id)
USERPROD(userid, productid, isbought, isfavorite, isowned)
or you may use one many-to-many support table for every relation is up to you
maybe you want another field "owner" in PRODUCTS table to store the user id. this is a one-to-one relation
What you want to do is actually describe the kind of relation between user and product: a favorite, or he 'owns' it.
Just add another field to the userproduct-table defining the relation: favorite or owned

CakePHP one to many Combo box

Hey I have two models User and City, where a user belongs to a city and a city has many users.
On the city table I have city_id and city_name.
I've used used cake bake and created the user model and when I add a new user the combos box under the city field is showing the id of the city instead of the name.
I've tried several methods to show the name of city instead of the id but I've failed.
You don't mention what you've tried, but usually you'd use the model's displayName property to set the field that should be used a record's "title". In your case, I'd think:
$this->displayName = 'city_name';
Note that in 1.3, it looks like the attribute name is displayField rather than displayName.
Cake requires a specific table layout for the automation to work. Rob explained how to get around it. But if you want to avoid writing the extra lines of code, you should consider organizing your tables accordingly.
CREATE TABLE `cities` (
`id` int(11) AUTO_INCREMENT NOT NULL,
`name` varchar(25) NOT NULL,
PRIMARY KEY (`id`)
)
When you bake this model, Cake will automatically use name as the display name. This will apply to every table you create. In addition, if you use id for the table, it will automatically know how to reference it as a foreign key from other tables as city_id.

Categories