Right relationships in Laravel - php

hello, sorry for my english. I will try explain my problem.
For example, we have model Product.
Each product has some options:
product_1 : option_1 = 50, option_2 = 14, option_3 = 23
Whats is the right way?
First - create database, like
id | title | option_1 | option_2 | option_3
Second - create models and tables, like
ProductModel hasMany optionModel
OptionModel belongsToMany ProductModel
tables in databases: Product, Option, Product_Option_Relationships
Third - create some collection in function and table Product_Option_Relationships like
$options = collect([
['id' => '1', 'name' =>'option1'],
['id' => '2', 'name' =>'option2'],
]);
Table: id | product_id | option_id
Or maybe exist normal way, because first - its too big table, when you have 20 options, second - create new model only for information function, i dont now, its normal? Third - too difficult in view show options name.
Thank you, i hope you understand me.

Generally use the one-to-many, many-to-many relationships
And the benefit for that you can freely edit any record without modifying the whole column to apply that on your tables :
First we have products table which is going to require options foreach
so we should have the table options which is going to combine the options in general then we add a new table assignOptionsToProducts which is include keys for both options & products in this case you're going to have many-to-many or one-to-many relationship as you like
Products Table
id | Name
1 | Product A
2 | Product B
Options Table
id | Name
1 | Option A
2 | Option B
AssignOptionsToProducts Table
id | Product_id | Option_id
1 | 1 | 1
2 | 1 | 2
3 | 2 | 2
As you can see we assigned the same option many times
And when we want to modify any option you can without modifying each record in other tables and of course you can use each table many times easily

Use the second way. You won't have repeated options. For example:
products
id | name
---|------
1 | Car
2 | Bike
options
id | name
-----|------------
1 | Transport
option_product
option_id | product_id
------------|-------------
1 | 1
1 | 2
Using the other ways, you would have the option Transport twice.

You can use many-to-many relationship and can structure it like so:
Product Model
class Product extends Model {
...
public function options() {
return $this->belongsToMany('App\Product', 'product_options', 'product_id', 'option_id');
}
}
Options Model
class Option extends Model {
...
public function product() {
return $this->belongsToMany('App\Option', 'product_options', 'option_id', 'product_id');
}
}
You will need three tables for this to work:
Table products
id | name
-----------------
1 | iBeacon
2 | Intel Edison
Table options
id | name
----------
1 | Price
2 | Size
Table product_options
id | option_id | product_id
---------------------------
1 | 1 | 2
2 | 2 | 2
You can choose if you want to store a record with the option value in the options table or in the pivot table. I'd place them in the pivot table to keep the options table smaller.
Now you'll be able to assign options to your products like so:
...
// Assing options to a product
$product->options()->sync([$optionID, $optionID]);
// Get product's options
$product->options;
// Get products having certain option
$option->products;
...

Related

Problem when getting records from database with relationship table

I'm having trouble relating photos to tags using an intermediate table.
In the example below, how can I select all photos that belong to tag 1 with an Eloquent relationship method in Laravel?
I have these tables:
-Photos Table
| id | name | description |
1 photo1.png ....
2 photo2.png ....
3 photo3.png ....
-Tags Table
| id | name |
1 Aesthetic
2 Dark
-Tags Relations
| id | tag_id | photo_id |
1 1 3
2 1 2
3 2 1
First of, you need to ensure that both Photos and Tags table have the relationship defined.
Under the Photos model you should have the following function:
public function tags() {
return $this->belongsToMany(
Tag::class,
"photos_tags", // the name of the pivot table
"photo_id",
"tag_id"
);
}
Under the Tags model you should have the following function:
public function photos() {
return $this->belongsToMany(
Photo::class,
"tags_photos", // the name of the pivot table
"tag_id",
"photo_id"
);
}
Now to access all the tags that are related to the Photo of id 1, you can call the following:
Photo::findOrFail(1)->tags()->get();
And the same you can do for a specific tag to get all it's photos.
Tag::findOrFail(1)->photos()->get();
Hope this will lead you to what you wish.

Symfony Doctrine - retrieve records from a related table using the foreign key field

I have two related tables. One of the table has a one to many relationship to the second table. This is a sample illustration of the two tables
**
registration
id | firstname | membershipfk
1 | John | 2
2 | Foo | 3
**
Here is illustration of the second table
membership
id | type | discount | description
1 | Gold | xyz | xyz description
2 | Silver | xyz | xyz description
Now my present challenge is to retrieve the membership fields from the membership table using the foreign key in the registration table.
For example: Select Type, Discount and Description from Membership Entity where fk in registration entity is equal to 2
Presently in my controller I am making this attempt
public function getMembersAction()
{
$restresults = $this->getDoctrine()->getRepository('XXXBundle:Members')->findAll();
$data = array();
foreach ($restresults as $restresult) {
array_push($data, $this->serializeData($restresult));
}
Every kind assistance is much appreciated
Try with the following code
$em->getRepository('XXXBundle:Members')
->createQueryBuilder('m')
->select("m.type, m.discount, m.description")
->innerJoin("XXXBundle:Registration","r","WITH","m.id = r.membershipfk") //Here you will Join with the Registration Bundle
->where("m.id = 2")
->getQuery()
->getResults();
you need to call a findBy for example if your entity are set well.
Try this:
$results = $this->getDoctrine()->getRepository('XXXBundle:Members')->findByMember($memberId);
But you need to have configured well your entity first

How to have multiple layers of hasMany() relation for Laravel 5?

Let say I have tables like the following:
order
order_id | customer_name | delivery_address
1 | David | ABC Road, DEF district
...........Some other record ..............
order_dish
order_id | dish_id | dish_name
1 | 1 | chicken wing
1 | 2 | meat pie
1 | 3 | onion ring
...........Some other record ..............
dish_ingredient
dish_id | ingredient
1 | chicken wing
1 | salt
1 | oil
2 | pork meat
2 | flour
3 | onion
...........Some other record ..............
In Laravel 5, if I want to get all dishes of an order, I can do:
$order = Order::hasMany('App\OrderDish', 'order_id')->get();
Is there a way I can get all ingredients needed for an order in one line?
Yes. The "has-many-through" relationship provides a convenient shortcut for accessing distant relations via an intermediate relation. You define it using hasManyThrough() method of your model.
First, define the relation in your Order model:
class Order extends Model {
public function ingredients() {
return $this->hasManyThrough('App\DishIngredient', 'App\OrderDish', 'order_id', 'dish_id');
}
}
With such a relation defined, you'll be able to get ingredients for given order with:
$ingredients = $order->ingredients;

Laravel - using ID's to represent values in another table

I have two tables for my vehicles website:
I have a table in my DB which contains all car makes:
ID | name | display_name
1 | audi | Audi
2 | bmw | BMW
I also have a vehicles table:
ID | VRM | make
1 | HW55VRM | 2
2 | VN62HHS | 1
When editing a vehicle this is the method for creating the view:
public function edit($id)
{
$vehicle = $this->vehicle->getSingle($id);
$makes = $this->vehicle->getMakes();
$models = $this->vehicle->getModels();
return View::make('admin.vehicles.edit', compact('makes', 'models', 'vehicle'));
}
On this view I have a select box:
{{ Form::select('make',$models , NULL, ['class' => 'form-control']) }}
Which correctly creates a select box with the options I need. However, I want to set one of these values as selected depending on the table row data.
So the first vehicle in my DB has '2' as its make. Which represents a BMW.
How can I add that to my $vehicles variable in the cleanest way? So I can just do
$vehicle->named_make
for example.
If you have Eloquent models then provided you have proper relationships defined you can do like that
$vehicle->make->display_name

Selecting 2 or more rows using an array (PHP, MYSQLi)

Ok, I wasnt sure how to title this.
I have 2 tables, one with products and one with merchants.
Some products can be sold by 2 or more merchants.
The products table has a column called 'product_merchant_id' with 1 or more references in it, like so.. '1237, 38272, 3738'
The id's are related to whats in the 'merchant_id' column in the 'merchants' table.
Merchant Table (merchants)
mer_id | merchant_id | merchant_name
-------------------------------------
1 | 1237 | Merchant One
2 | 38272 | Merchant Two
3 | 3738 | Merchant Three
Product Table (products)
product_id | product_merchant_id | product_name
------------------------------------------------------------
1 | 1237, 38272 | Sample Product One
2 | 1237, 3738, 38272 | Sample Product Two
3 | 3728 | Sample Product Three
So, basically, if I was querying product_id 2, I want to be able to pull 2 rows with the merchant_id's of 1237 & 38272 from the merchant table and loop them in my template, something like...
<div>
<p>Merchant Name: Merchant One</p>
<p>Merchant ID: 1237</p>
</div>
<div>
<p>Merchant Name: Merchant Two</p>
<p>Merchant ID: 38272</p>
</div>
The solution is to change your table structure. Remove the product_merchant_id column in the Product table, then create a new table, called product_merchants, with two columns: product_id and merchant_id. It will look something like:
product_id | merchant_id
--------------------------
1 | 1237
1 | 38272
2 | 1237
2 | 2728
2 | 38272
3 | 3738
Now, you can use a join to get all the information you need. Something like this should work:
SELECT m.merchant_name, m.merchant_id
FROM merchants m
JOIN product_merchants mp ON m.merchant_id = mp.merchant_id
AND mp.product_id = 2
See demo
Something like this can help:
Select * from merchants where merchant_id in ((select product_merchant_id from products where product_id=2))
I believe this should work.
My advice is you can add one table that like stock table that will be mapped product_id and merchant_id and you will get stock_id it will make easier for development

Categories