Model relationships in Laravel 5.3 - php

I've got MySQL tables for site cart:
Cart:
id | user
Cart_goods:
cart_id | good_id | good_type
Details:
id | name
Appliances:
id | name
Class Cart, which contains goods:
class Cart extends Model
{
protected $table = 'cart';
protected $fillable = ['user', 'sum', 'profit', 'discount'];
protected $guarded = ['user'];
public function goods()
{
return $this->hasMany('App\Models\Good');
}
}
Class Good, which can be Detail or Appliance and relative to cart by cart_id:
class Good extends Model
{
protected $table = 'cart_goods';
protected $types = [
'Detail' => 'App\Models\Detail',
'Appliance' => 'App\Models\Appliance'
];
public $primaryKey = 'cart_id';
public function good()
{
return $this->morphTo();
}
}
Detail class:
class Detail extends Model {
use SoftDeletes;
protected $morphClass = 'Detail';
protected $table = 'details';
protected $fillable = ['article', 'name', 'photo', 'price_procurement', 'price_retail', 'serial', 'location_id', 'type_id', 'appliance_id', 'comment', 'for'];
protected $dates = ['deleted_at'];
protected $guarded = [];
public function goods()
{
return $this->morphMany('App\Models\Good', 'good');
}
}
And i need to get all appliances and details in cart. How can i do it by using ORM?

Use nested eager loading. Assuming that relationship method names are cartGoods, details and appliances, that details are details of a cart and that you've defined the relationships right:
Card::where('id', $id)
->with('cartGoods.appliances', 'details')
->first();

Try this:
Method 1: If you have a $cart model instance
$cart->load('goods.good');
Method 2: If you need all appliances and details from cart by card ID
Cart::where('id', $cartId)->with('goods.good')->first();

I've done this, problem was in model name, i was writing it to DB like Detail and Appliance, but i was need to use
Relation::morphMap([
'detail' => 'App\Models\Detail',
'appliance' => 'App\Models\Appliance',
]);
In AppServiceProvider class.

Related

Simple laravel models usage

My model:
class Product extends Model
{
protected $table = 'Products';
protected $fillable = ['product_code', 'type', 'name', 'description', 'price', 'discount', 'image', 'image_alt'];
public function products()
{
return $this->hasMany('App\ProductSpecifics');
}
}
My controller code:
public function product($code)
{
$product = Product::where('product_code',$code)->get();
$productSpec = ProductSpecifics::where('product_code',$code)->get();
var_dump($product->name);
return view('pages.product', compact('product','productSpec'));
}
Error:
Property [name] does not exist on this collection instance
I tried using dd($product) and I noticed that there is a lot of information in there.
How do I extract only the attributes like name,type & etc ?
try this
dd($product->toArray());

Accessing Pivot table "3rd Model relationship" in Laravel Eloquent

I have this Many-to-Many relation Laravel Eloquent relationship
The Models are:
class Email extends Model //actually represent the email account
{
protected $table = 'emails';
protected $fillable = [
'user_id',
'name',
];
public function messages() {
return $this->belongsToMany(Message::class)->withPivot('email_subtype_id');
}
}
class Message extends Model //actually represent the email message
{
protected $table = 'messages';
protected $fillable = [
'subject',
'body ',
];
public function emails() {
return $this->belongsToMany(Email::class)->withPivot('email_subtype_id');
}
}
class EmailMessage extends Pivot //actually represent the pivot table
{
protected $table = 'email_message';
protected $fillable = [
'email_id',
'message_id',
'email_subtype_id',
];
public function email() {
return $this->belongsTo(Email::class);
}
public function message() {
return $this->belongsTo(Message::class);
}
//this is the relation to a third model called EmailSubtype
//I want to include this relation to the Pivot when using it
public function subtype() {
return $this->belongsTo(EmailSubtype::class, 'email_subtype_id');
}
}
class EmailSubtype extends Model //3rd Model need to be included with Pivot
{
protected $table = 'email_subtypes';
protected $fillable = [
'name'
];
public function pivotEmailSubtype(){
return $this->hasMany(Pivot::class, 'email_subtype_id');
}
}
I am able to do this in the Controller:
$email = Email::find(1);
foreach($email->messages as $message) {
$subtype_id = $message->pivot->email_subtype_id;
dd($subtype_id); //1 that relates to subtype: CC Email Account
//also I can get the name indirectly away from the relation as follows:
$subtypeName = EmailSubtype::find($subtype_id)->first()->name;
dd($subtypeName);
}
Here I am getting the email_subtype_id only by direct pivot relation but have to do extra work to get the related email sub-type name.
I need to get the email sub-type name [Directly] from the 3rd Model EmailSubtype relationship oneToMany [hasMany and belongsTo] that relates to Pivot model with EmailSubtype model using something like:
$message->pivot->subtypeName;
Any help please!
Use this:
public function messages() {
return $this->belongsToMany(Message::class)->withPivot('email_subtype_id')
->using(EmailMessage::class);
}
$message->pivot->subtype->name

How To Update Laravel hasMany Relationship Models?

I've been trying to wrap my head on figuring out how to update my hasMany relationship model. I can easily create new relationships but when I try to update my relationship model it does not work? Does laravel push() method still work? Can anyone help please? For example I want to update my Taxonomy Table thats related to my Products table within my Controller. I have a code snippet below::
Product.php
class Product extends Model
{
protected $fillable = [
'product_category', 'product_subcategory', 'product_name',
'product_price', 'product_id', 'product_description', 'product_image'
];
protected $primaryKey = 'product_id';
public $incrementing = false;
public function addTaxonomiesToProduct()
{
return $this->hasOne('App\Taxonomies', 'product_id', 'product_id');
}
}
Taxonomies.php
class Taxonomies extends Model
{
protected $fillable = ['product_category', 'product_subcategory'];
protected $primaryKey = 'product_id'; // or null
public $incrementing = false;
public function product()
{
return $this->belongsTo(Product::class);
}
}
EditProductController.php
class EditProductController extends Controller
{
public function update(Request $request, Product $product)
{
$product_size = array();
foreach ($request->product_size as $key => $value)
{
array_push($product_size,$value);
}
$product->update([
'product_name' => $request->product_name,
'product_price' => $request->product_price,
'product_description' => $request->product_description,
'product_size' => serialize($product_size),
'product_image' => $product_image_path,
]);
/**
* Go the products table,
* Get the product based off its product_id,
* and then update this products taxonomy
**/
$taxonomies = Product::find($product->product_id);
$taxonomies->addTaxonomiesToProduct->product_subcategory = "Mens Shoes";
$taxonomies->push();
}
}
****Update Issued Solved****
By changing hasMany() to hasOne() within my Products table, my taxonomies table updated correctly.
I think you don't fully understand the way Laravel Eloquent relationships work. First off, you need to define the relationship in both models.. Your Taxonomy model has this, but your Product model should have:
public function taxonomies()
{
return $this->hasMany('App\Taxonomies', 'product_id', 'product_id');
}
Then to update a Product's taxonomies, you'd have something like...Uh, I'm not sure what you're trying to achieve here, especially with the way you chained the product_subcategory, so I can't rightly say, but do see the documentation

Laravel 4 - foreign key constraint fails

I have the following relations:
Discount:
<?php
class Discount extends Eloquent {
protected $table = 'discount';
public $timestamps = true;
public function title()
{
return $this->hasOne('Translation', 'labelId', 'titleLabelId')->where('languageId', T::getLang())->first()['phrase'];
}
public function titles()
{
return $this->hasMany('Translation', 'labelId', 'titleLabelId');
}
}
?>
Translation:
<?php
class Translation extends Eloquent {
protected $table = 'translations';
public $timestamps = false;
protected $fillable = array('phrase', 'languageId', 'labelId');
public function language()
{
return $this->belongsTo('Language', 'languageId');
}
public function label()
{
return $this->belongsTo('Label', 'labelId');
}
}
?>
Label:
<?php
class Label extends Eloquent {
protected $table = 'label';
public $timestamps = false;
protected $fillable = array('key');
public function translations()
{
return $this->hasMany('Translation', 'labelId', 'id');
}
}
?>
There are three database tables with the following columns:
Discount:
id | titleLabelId
Translation:
id | languageId | labelId
Label:
id
The problem: I'd like to create a title (translation) and associate it with the discount. Here's what I've tried:
$discount = new Discount;
/*create a new label*/
$labelKey = Label::max('key') + 1;
$label = new Label(array('key' => $labelKey));
$label->save();
/*create a new title (and associate it with the label)*/
$title = new Translation(
array(
'phrase' => $input['title'],
'languageId' => 3,
'labelId' => $label->id
));
$title->save();
$discount->save();
$discount->titles()->save($title);
Apparently, the $discount->titles()->save($title); part doesn't work. The title is only attached to the discount if I do it manually: $discount->titleLabelId = $label->id. Is there a way to do it using the ORM?
In your Discount Model, do you have your relationship set up to use the proper table and foreign key?
class Discount extends Eloquent
{
public function titles()
{
return $this->belongsTo('Translation', 'translations', 'titleLabelId');
}
}
When trying to associate one model with another through a defined relationship in Eloquent, you should use the associate() method rather than the save() method.
$discount->titles()->associate($title);
Before this happens though, you should be sure to call the save() method on anything that has been altered or is new.

How to use the `where` method along with the `with` method in laravel 4?

Given the following, very simple, example:
Country Class
class Country extends Eloquent {
protected $table = "countries";
protected $fillable = array(
'id',
'name'
);
public function state() {
return $this->hasMany('State', 'country_id');
}
}
State Class
class State extends Eloquent {
protected $table = "states";
protected $fillable = array(
'id',
'name',
'country_id' #foreign
);
public function country() {
return $this->belongsTo('Country', 'country_id');
}
}
How can I list all the states, based on the id or the name of the country.
Example:
State::with('country')->where('country.id', '=', 1)->get()
The above returns an area, as country is not part of the query (Eloquent must attach the join later, after the where clause).
I think you're either misunderstanding the relations or over-complicating this.
class Country extends Eloquent {
public function states() {
return $this->hasMany('State', 'state_id');
}
}
$country = Country::find(1);
$states = $country->states()->get();

Categories