模型的关系(Laravel 5.2) [英] Relationships of models (Laravel 5.2)

查看:106
本文介绍了模型的关系(Laravel 5.2)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的表(Mysql DB):



//存储表

  CREATE TABLE IF NOT EXISTS`app_beta`.`stores`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50)NOT NULL,
PRIMARY KEY( `id`))

//项目表




`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT UNSIGNED NOT NULL,
`title` TEXT NOT NULL,
`content` LONGTEXT NULL,
PRIMARY KEY(`id`),
CONSTRAINT`fk_items_user_id`
FOREIGN KEY(`user_id `)
参考`app_beta`.`users`(`id`))

/ /产品表

  CREATE TABLE IF NOT EXISTS`app_beta`.`products`(
`id` INT UNSIGNED NOT NULL,
`comments` DECIMAL(7,1)NOT NULL,
PRIMARY KEY(`id`),
CONSTRAINT`fk_products_id`
FOREIGN KEY(`id`)
参考`app_beta`.`items`(`id`))

// Product_Store Table

  CREATE TABLE IF NOT EXISTS` app_beta`.`products_stores`(
`product_id` INT UNSIGNED NOT NULL,
`store_id` INT UNSIGNED NOT NULL,
`price` DECIMAL(7,2)NOT NULL,
`url` VARCHAR(255)NOT NULL,
CONSTRAINT`fk_products_store_product_id`
FOREIGN KEY(`product_id`)
参考`app_beta`.`products`(`id`),
CONSTRAINT`fk_products_stores_store_id`
FOREIGN KEY(`store_id`)
参考`app_beta`.`stores`(`id`))

//提供表

  CREATE TABLE IF NOT EXISTS`app_beta` .`offers`(
`id` INT UNSIGNED NOT NULL,
`store_id` INT UNSIGNED NOT NULL,
`price` DECIMAL(7,2)NULL,
`url `VARCHAR(255)NOT NULL,
`start_date` DATE NOT NULL,
`end_date` DATE NOT NULL,
PRIMARY KEY(`id`),
CONSTRAINT`fk_offers_store_id`
FOREIGN KEY(`store_id`)
参考`app_beta`.`stores`(`id`),
CO NSTRAINT`fk_offers_id`
FOREIGN KEY(`id`)
参考`app_beta`.`items`(`id`))

添加。信息:



我的表已迁移。只是为了澄清...产品和报价继承自物品表。如果项目未创建,我无法添加产品和优惠。



产品可以有标题,摘要,内容,类别等。




  • 该产品可以在1个以上的商店

  • 优惠仅限于1-1个商店。



如果我错了我知道! / p>

**请,我希望有人帮助我创建项目模型,产品和报价之间的关系。我可以使用多态关系吗? **



模型完成:

 类商店扩展模型
{
public function offers()
{
return $ this-> hasMany('App\Offer');
}

public function products()
{
return $ this-> hasMany('App \Product');
}
}

class产品扩展模型
{
public function stores()
{
return $ this-> ; belongsToMany( 'App\Store');
}
}

class Offer extends
{
public function store()
{
return $ this-> ;属于关联( 'App\Offer');
}
}

使用php工匠修补程序,一切都很好!

 命名空间App 

$ user = new用户
$ store = new Store

$ item = new Item
$ item-> id = 1
$ item-> user_id = 1
$ item-> title ='test'
$ item-> content'test'
$ item-> save();
true

$ item2 = new Item
$ item2-> id = 2
....
true

$ product1 = new Product
$ product1-> id = 1(FK item-> id)
$ product1-> reviews = 5
$ product1-> save()
true

$ offer1 = new Offer
$ offer1-> id = 2(FK item-> id)
$ offer1-> store_id = 1

...
true

我稍后再添加将产品附加到一个或多个商店的功能(products_stores表)。



谢谢。

解决方案

这是我以为你可以有一个很好的开始...



首先,您的模型和迁移可以处理所有这些。



有关系: Laravel 5.2 Relationship
有迁移: Laravel 5.2迁移



所以你创建你的迁移:

  Schema :: create('stores',function(Blueprint $ table){
$ table-> bigIncrements('id') - > unsigned();
$ table-> string('name',50);
$ table-> timestamps();
});

Schema :: create('items',function(Blueprint $ table){
$ table-> bigIncrements('id') - > unsigned();
$ table-> bigInteger('user_id') - > unsigned();
$ table-> foreign('user_id') - > references('id') - > on('users' );
$ table-> text('title');
$ table-> longText('content');
$ table-> timestamps();
});

Schema :: create('products',function(Blueprint $ table){
$ table-> bigIncrements('id');
$ table-> bigInteger ('store_id') - > unsigned();
$ table-> foreign('store_id') - > references('id') - > on('stores');
$ table-> decimal('reviews',7,1);
$ table-> timestamps();
});

Schema :: create('offers',function(Blueprint $ table){
$ table-> bigIncrements('id');
$ table-> bigInteger ('store_id') - > unsigned();
$ table-> foreign('store_id') - > references('id') - > on('stores');
$ table-> bigInteger('item_id') - > unsigned();
$ table-> foreign('item_id') - > references('id') - > on('items' );
$ table-> decimal('price',7,2);
$ table-> string('url',255);
$ table-> dte ('start_date');
$ table-> dte('end_date');
$ table-> timestamps();
});

所以,一旦你这样做,你可以把你的关系放在你的模型上。这样你就不需要所有的中间表。当您使用associate()时,Laravel将为您创建链接。这样你可以这样做:$ offer-> store() - > name来获取当前报价的商店名称。看看:



进入商店的模型

 公共功能产品)
{
return $ this-> hasMany(Product :: class);
}

public function offers()
{
return $ this-> hasMany(Offer :: class);
}

进入优惠模式

  public function store()
{
return $ this-> belongsTo(Store :: class);
}

这样,您创建一对多关系。我说过,$ offer-> store()会检索该报价的商店。 $ store-> offer() - > get()将检索商店的所有优惠。



希望它有帮助。



编辑



我所说的只有一个问题。 n + 1问题。所以就这样解释(搜索googlelaravel n + 1问题,并选择链接到laracast)(不能把它当作一个链接,没有足够的声誉),当你打电话给我说的话,脚本会做2查询。当你使用foreach()循环时,它会有一个循环+1查询。我建议你做这样的事情

  $ offers = Offer :: with('store') - > all() ; 

这样你只有一个查询,你仍然可以做

  $ offer-> store; 

而不执行其他查询。



你使用$ model = Model :: with('something') - > all();查询将从2表中获取数据,并将结果返回到数组中。像这样:

 提供{
[0]:{a,b,c,d,e,store { a,b,c,d,e}}
[1]:{a,b,c,d,e,store {a,b,c,d,e}}
[2] :{a,b,c,d,e,store {a,b,c,d,e}}
[3]:{a,b,c,d,e,store {a,b, c,d,e}}
}

可以使用相反的方法:

  $ stores = Store :: with('offers') - > all(); 

所以你可以使用:

  $ store->优惠[Ⅰ]  - >财产以后; 

因为数组将如下所示:

  store {
[0]:{a,b,c,d,e,offers {
[0]:{a,b,c,d ,e}
[1]:{a,b,c,d,e}
[2]:{a,b,c,d,e}
[3] a,b,c,d,e}
}}
[1]:{a,b,c,d,e,offers {
[0] c,d,e}
[1]:{a,b,c,d,e}
[2]:{a,b,c,d,e}
[3 ]:{a,b,c,d,e}
}}
[2]:{a,b,c,d,e,offers {
[0] ,b,c,d,e}
[1]:{a,b,c,d,e}
[2]:{a,b,c,d,e}
[3]:{a,b,c,d,e}
}}
}


My tables (Mysql DB):

// Stores Table

CREATE TABLE IF NOT EXISTS `app_beta`.`stores` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
 PRIMARY KEY (`id`))

// Items Table

 CREATE TABLE IF NOT EXISTS `app_beta`.`items` (
 `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
 `user_id` INT UNSIGNED NOT NULL,
 `title` TEXT NOT NULL,
 `content` LONGTEXT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `fk_items_user_id`
  FOREIGN KEY (`user_id`)
  REFERENCES `app_beta`.`users` (`id`))

// Products Table

CREATE TABLE IF NOT EXISTS `app_beta`.`products` (
`id` INT UNSIGNED NOT NULL,
`reviews` DECIMAL(7,1) NOT NULL,
 PRIMARY KEY (`id`),
 CONSTRAINT `fk_products_id`
 FOREIGN KEY (`id`)
REFERENCES `app_beta`.`items` (`id`))

// Product_Store Table

CREATE TABLE IF NOT EXISTS `app_beta`.`products_stores` (
`product_id` INT UNSIGNED NOT NULL,
`store_id` INT UNSIGNED NOT NULL,
`price` DECIMAL(7,2) NOT NULL,
`url` VARCHAR(255) NOT NULL,
 CONSTRAINT `fk_products_store_product_id`
 FOREIGN KEY (`product_id`)
 REFERENCES `app_beta`.`products` (`id`),
 CONSTRAINT `fk_products_stores_store_id`
 FOREIGN KEY (`store_id`)
 REFERENCES `app_beta`.`stores` (`id`))

// Offers Table

CREATE TABLE IF NOT EXISTS `app_beta`.`offers` (
`id` INT UNSIGNED NOT NULL,
`store_id` INT UNSIGNED NOT NULL,
`price` DECIMAL(7,2) NULL,
`url` VARCHAR(255) NOT NULL,
`start_date` DATE NOT NULL,
`end_date` DATE NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_offers_store_id`
FOREIGN KEY (`store_id`)
REFERENCES `app_beta`.`stores` (`id`),
CONSTRAINT `fk_offers_id`
FOREIGN KEY (`id`)
REFERENCES `app_beta`.`items` (`id`))

Add. Info:

My tables are migrated. Just to clarify... the products and offers inherit from the items table. If the item is not created I can not add products and offers.

The product can have the title, summary, content, category etc... same for the offer.

  • The product can be on 1-many stores
  • The offer can be only on 1-1 store.

If I'm wrong LET ME KNOW!

** Please, I want someone to help me creating the relationships between the Item model, product and offer. Can i use polymorphic relations? **

Models DONE:

class Store extends Model
{
public function offers()
{
    return $this->hasMany('App\Offer');
}

public function products()
{
    return $this->hasMany('App\Product');
}
}

class Product extends Model
{
public function stores()
{
    return $this->belongsToMany('App\Store');
}
}

class Offer extends Model
{
public function store()
{
    return $this->belongsTo('App\Offer');
}
}

using php artisan tinker, all works nice!

namespace App

$user = new User
$store = new Store

$item = new Item
$item->id = 1
$item->user_id = 1
$item->title = 'test'
$item->content 'test'
$item->save();
true

$item2 = new Item
$item2->id = 2
....
true

$product1 = new Product
$product1->id = 1 (FK item->id)
$product1->reviews = 5
$product1->save()
true 

$offer1 = new Offer
$offer1->id = 2 (FK item->id)
$offer1->store_id = 1

...
true

I'll add later a function to attach product to one or many stores (products_stores table).

Thanks.

解决方案

This is how I think you can have a good start...

First of all, your model and migration can handle all it.

There is for relationship:Laravel 5.2 Relationship There is for migration:Laravel 5.2 Migration

So there you create your migration:

Schema::create('stores', function (Blueprint $table) {
    $table->bigIncrements('id')->unsigned();
    $table->string('name', 50);
    $table->timestamps();
});

Schema::create('items', function (Blueprint $table) {
    $table->bigIncrements('id')->unsigned();
    $table->bigInteger('user_id')->unsigned();
    $table->foreign('user_id')->references('id')->on('users');
    $table->text('title');
    $table->longText('content');
    $table->timestamps();
});

Schema::create('products', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->bigInteger('store_id')->unsigned();
    $table->foreign('store_id')->references('id')->on('stores');
    $table->decimal('reviews', 7,1);
    $table->timestamps();
});

Schema::create('offers', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->bigInteger('store_id')->unsigned();
    $table->foreign('store_id')->references('id')->on('stores');
    $table->bigInteger('item_id')->unsigned();
    $table->foreign('item_id')->references('id')->on('items');
    $table->decimal('price', 7,2);
    $table->string('url', 255);
    $table->dte('start_date');
    $table->dte('end_date');
    $table->timestamps();
});

So, once you did this, you can make your relationship onto your model. This way you don't need all the "between" tables. When you will use associate(), Laravel will create the link for you. This way you can do something like this: $offer->store()->name to get the name of the store of the current offer. Take a look:

Into Store's model

public function products()
{
    return $this->hasMany(Product::class);
}

public function offers()
{
    return $this->hasMany(Offer::class);
}

Into Offer's model

public function store()
{
    return $this->belongsTo(Store::class);
}

This way, You create a one-to-many relation. Has I said, $offer->store() will retrieve the store of the offer. $store->offers()->get() will retrieve all offer of the store.

Hope it help.

EDIT

There is one only problem with what I said. The n + 1 problem. So like it explain there(search google "laravel n+1 problem" and pick the link to laracast) (can't put it as a link, not enough reputation) , when you call things like I said, the script will do 2 query. When you use a foreach() loop, it'll have as much loop +1 query. I suggest you to do things like that

$offers = Offer::with('store')->all();

This way you'ill have only 1 query and you will still able to do

$offer->store;

without doing another query.

When you use $model = Model::with('something')->all();, the query will fetch data from 2 table and return the result with an array into an array. Like this:

offers {
    [0]:{a,b,c,d,e, store{a,b,c,d,e}}
    [1]:{a,b,c,d,e, store{a,b,c,d,e}}
    [2]:{a,b,c,d,e, store{a,b,c,d,e}}
    [3]:{a,b,c,d,e, store{a,b,c,d,e}}
}

You can use the opposite:

$stores = Store::with('offers')->all();

So you can use:

$store->offers[i]->somthing;

Because the array will look like this:

stores {
    [0]:{a,b,c,d,e, offers{
                        [0]:{a,b,c,d,e}
                        [1]:{a,b,c,d,e}
                        [2]:{a,b,c,d,e}
                        [3]:{a,b,c,d,e}
                        }}
    [1]:{a,b,c,d,e, offers{
                        [0]:{a,b,c,d,e}
                        [1]:{a,b,c,d,e}
                        [2]:{a,b,c,d,e}
                        [3]:{a,b,c,d,e}
                        }}
    [2]:{a,b,c,d,e, offers{
                        [0]:{a,b,c,d,e}
                        [1]:{a,b,c,d,e}
                        [2]:{a,b,c,d,e}
                        [3]:{a,b,c,d,e}
                        }}
}

这篇关于模型的关系(Laravel 5.2)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆