I have two tables:
product: id | name | category
productimage: id | imagename | productid
I want to take results in this form:
[{
"id":1,
"name":"abc",
"category":1,
"imagename":[
{
"id":1,
"imagename":abc.jpg
},
{
"id":2,
"imagename":abc1.jpg
},
{
"id":3,
"imagename":abc2.jpg
}]
}]
and I have two models:
call:
= product
= productimage
<?php
class Product extends \Eloquent {
//protected $fillable = [];
protected $table = 'product';
public function productimage(){
return $this->hasMany('productimage');
}
}
<?php
class Productimage extends \Eloquent {
//protected $fillable = [];
protected $table = 'productimage';
public function product(){
return $this->belongsTo('product');
}
}
This is taken directly from the Laravel documentation:
Define the relationship in the model, i assume that one product can only have one product image:
class Product extends Eloquent {
public function productimage()
{
return $this->hasOne('Productimage');
}
}
Get product image for the product with ID of 1:
$image = Product::find(1)->productimage;
Related
I want to fetch 2 products from every category.
Product.php
class Product extends Model
{
protected $table = 'products';
}
Category.php
class Category extends Model {
protected $table = 'categories';
}
Controller
public function index() {
$products = Product::all();
return Product::latest()->take(5)->get();
}
This should fetch the first two products of each category:
// Get all categories
$categories = Category::all();
//Create an empty array to store our product IDs
$prodIds = array();
// Extract the first 2 product IDs in each category
foreach ($categories as $category) {
$prodIds[] = $category->products->take(2)->pluck('id');
}
// Fetch products from their IDs
$products = Product::findMany($prodIds);
Edit: Also my answer above should work, it will fail if the category doesn't have at least two products. To fix this, you would need to remove empty values from $prodIds.
Product.php
class Product extends Model
{
protected $table = 'products';
public function Category()
{
return $this->belongsTo(Product::class);
}
}
Note : import your category model in Category model
Category.php
class Category extends Model {
protected $table = 'categories';
public function Product()
{
return $this->hasMany(Product::class);
}
}
Note : import your category model in Product model
Controller
public function index() {
return Category::with('Product'=>funcation($obj){
return $obj->take(2);
})->latest()->take(5)->get();
}
try this
$products = Product::latest()->take(2)->with('categories')->get();
I cannot figure out how to define one to many relation using Eloquent.
Here are tables
----------- Country -----------
id | title | code | currency_code
----------- Currency Code --------
id | name | symbol | code
One country may have many currencies.
Therefore I defined my models as follows
class Country extends Model
{
public function currencies()
{
$this->hasMany('App\Models\Currency', 'code', 'currency_code');
}
}
And the Currency model is simple
class Currency extends Model
{
}
And I am selecting countries like that
return Country::all('country_id AS value', 'title_ru AS title','currency_code')
->sortBy('value');
But it returns null when I try to access currencies
What is wrong with my definitions, I would be grateful for any help.
Thanks
You can set your model like the following code:
Country model:
class Country extends Model
{
protected $table = 'country';
protected $primaryKey = 'id';
public function currency(){
return $this->hasMany(App\Models\Currency', 'code', 'currency_code');
}
}
Currency model:
class Currency extends Model
{
protected $table = 'currency';
protected $primaryKey = 'id';
public function country(){
return $this->belongTo('App\Models\Country', 'code');
}
}
And then if you wanna get a specific country data (with currency) you can use this:
$data = County::where('id','=',$id)->with('currency')->first();
Or if you wanna get everything you can use:
$data = County::with('currency')->get();
You should try this:
Country Model
class Country extends Model
{
public function currencies()
{
$this->belongsTo('App\Models\Currency', 'currency_code');
}
}
Currency Model
class Currency extends Model
{
public function country()
{
$this->belongsTo('App\Models\Country');
}
}
In my case, I have two table like users table and rating table.
In user table, I'm storing user's personal details like name, email etc,
In rating table, I'm storing user_id and rating(rating will be in numbers like 1,2,3,4 and 5)
I have created relationship two tables
here is the relation
//User Model
public function ratings()
{
return $this->hasMany(Rating::class);
}
//Rating model
public function user()
{
return $this->belongsTo(Consultant::class);
}
I can able to display get data with eager loading
$data = User::with('ratings')->get();
The Response I'll get from eager load is
[
{
"id": 1,
"cunsultant_name": "Quincy Jerde",
"contact_number": "882-904-3379",
"ratings": [
{
"user_id": 1,
"rating_for_user": 3
},
{
"user_id": 1,
"rating_for_user": 5
},
{
"user_id": 2,
"rating_for_user": 3
}
]
},
{
"user_name": "Alene Dicki",
"contact_number": "247.604.8170",
"ratings": [
{
"id": 4,
"user_id": 3,
"rating_for_user": 3
}
]
}
]
So how can I get an average rating for every user with eager loading?
To get the average rating with eager loading you can do
$user->ratings()->avg('rating_for_user');
This will always append average_rating field in product. I use morph relation for ratings but you can use any relation appropriate for your situation.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Product extends Model
{
protected $guarded = [];
protected $appends = ['average_rating'];
public function ratings()
{
return $this->morphMany(Rating::class, 'rateable');
}
public function getAverageRatingAttribute()
{
return $this->ratings()->average('value');
}
}
You can do it like this,
$data = User::with('ratings')
->join('Rating table','user.id','=','Rating table.user_id')
->select('user.*',DB::raw('avg(rating_for_user)'))
->get();
Modify the code as per your need.
I hope it help.
If you want to get ratings of multiple users you can do like this.
$users = User::where('type', 'instructor')->get();
foreach ($users as $user) {
$user['ratings'] = $user->ratings()->avg('rate');
}
return $users;
You can get avg rating like this,
$product=Products::where('id',$productid);
$data=$product->with('ratings')->get();
foreach($data as $d) {
return $d->ratings->avg('rating');
}
I have added code for product avg rating where two model like below:
Product Model:
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\URL;
class Products extends Model {
protected $table = "products";
public $timestamps = false;
public function ratings()
{
return $this->hasMany("App\Model\Reviews","p_id");
}
}
Review Model:
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class Reviews extends Model
{
protected $table = "product_reviews";
public $timestamps = false;
//Rating model
public function products()
{
return $this->belongsTo("App\Model\Products");
}
}
I have 3 models objects, namely: Categories, Category_products & Products
Categories:
<?php
class Categories extends Model
{
protected $table = 'categories';
public function product_ids() {
return $this->hasMany("app\Models\categories\Category_products", "category_id", "id");
}
?>
Category_products:
<?php
class Category_products extends Model
{
protected $table = 'category_products';
public function product_ids(){
return $this->belongsTo('app\Models\categories\Category');
}
public function products(){
return $this->hasOne("app\Models\Product", "id", "product_id");
}
}
?>
And Product:
<?php
class Product extends Model {
protected $table = 'products';
public function product(){
return $this->belongsTo("app\Models\categories\Category_products");
}
?>
Now in my CategoryController I do:
$this->data["products"] = Categories::find($id)->product_ids()->products()->get();
But now I get an error :
Call to undefined method Illuminate\Database\Query\Builder::products()
How can I do this the right way ?
OK, I'm going to try.
I guess you missed something when reading the Laravel documentation.
You don't have to create the category_products Models because it's your pivot table between your Categories and your Product.
"Normally", you should have something like this :
Products :
. id
. name
Categories :
. id
. name
category_product (alphabetically ordered name)
. product_id
. category_id
And your Models:
class Category extends \Eloquent {
public function products()
{
return $this->belongsToMany('namespace\to\your\model\Product');
}
}
class Product extends \Eloquent {
public function categories()
{
return $this->belongsToMany('namespace\to\your\model\Category');
}
}
Then you can do the following :
$this->data["products"] = Category::find($id)->products;
or
$this->data["products"] = Category::find($id)->products()->get();
Laravel will take care to call the pivot table for you.
It's not common to name your class with a plural, get used to name your class with their singular
And see also : http://laravel.com/docs/5.0/eloquent#many-to-many
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.