Retriving two models and order them by date - php

I'm trying to retrive the 20 most recent elements from two differents models Post and Link and rank them by the field created_at in descending order.
Here is the link class
class Link extends \Illuminate\Database\Eloquent\Model {
public $incrementing = false;
public function author() {
return $this->belongsTo('App\Models\Author');
}
public function category() {
return $this->belongsTo('App\Models\Category');
}
}
And here the post class
class Post extends \Illuminate\Database\Eloquent\Model {
public $incrementing = false;
public function author() {
return $this->belongsTo('App\Models\Author');
}
public function category() {
return $this->belongsTo('App\Models\Category');
}
}
How can I do that with eloquent (I'm using it outside Laravel, with Slim)?

use the below code to get recent records
orderBy('created_at', 'DESC')->get();

The merge method was the answer :
$posts = \App\Models\Post::where('draft', false)->orderBy('created_at', 'desc')->take(20)->get();
$links = \App\Models\Link::orderBy('created_at', 'desc')->take(20)->get();
$result = $posts->merge($links)->sortByDesc('created_at')->take(20);

Related

How to get only active element from many to many relationship with translation in laravel

I have a problem with a many to many relationship and the translations of the terms.
I have 4 tables:
products
- id, price, whatever
products_lang
- id, product_id, lang, product_name
accessori
- id, active
accessori_lang
- id, accessori_id, lang, accessori_name
I'm trying to assign accessories to products with an intermediate table named:
accessori_products
this is the model for Product:
class Product extends Model {
protected $table = 'products';
public function productsLang () {
return $this->hasMany('App\ProductLng', 'products_id')->where('lang','=',App::getLocale());
}
public function productsLangAll() {
return $this->hasMany('App\ProductLng', 'products_id');
}
public function accessori() {
return $this->belongsToMany('App\Accessori', 'accessori_products');
}
}
this is the model for productLng:
class ProductLng extends Model {
protected $table = 'products_lng';
public function products() {
return $this->belongsTo('App\Product', 'products_id', 'id');
}
}
Then I have the model for Accessori:
class Accessori extends Model {
protected $table = 'accessori';
public function accessoriLang() {
return $this->hasMany('App\AccessoriLng')->where('lang','=',App::getLocale());
}
public function accessoriLangAll() {
return $this->hasMany('App\AccessoriLng');
}
public function accessoriProducts() {
return $this->belongsToMany('App\Products', 'accessori_products', 'accessori_id', 'products_id');
}
}
And the model for AccessoriLng:
class accessoriLng extends Model {
protected $table = 'accessori_lng';
public function accessori() {
return $this->belongsTo('App\Accessori', 'accessori_id', 'id');
}
}
I get the results by this:
$products = Product::has('accessori')->with([
'productsLang ',
'accessori' => function ($accessori){
$accessori->with([
'accessoriLang'
]);
}
])->get();
return $products;
but I want to get only the active accessories something like where accessori.active = 1 but I really don't know where to put it. I've tried in different way but I'm stuck on it by 2 days.
IIRC you don't need a model for the intermediate table on your many to many relationships.
If you want to return Products where Accessori is active you can use whereHas on the Product model.
$prod = Product::whereHas('accessori', function($query) {
$query->where('active', 1);
})->get();
Where the $query param will be running on the Accessori model.
You can do the inverse as well with Accessori to Product.
$acessoris = Accessori::where('active', 1)->whereHas('accessoriProduct')->with(['accessoriLang', 'accessoriProducts.productsLang'])->get();

Laravel 5.6: Relationship with multiple tables and conditions

Consider I'm a hotel owner, and I have to know the bookings related to my hotel.
I need all bookings that which associated with my hotel.
Is there any eloquent functions to join? How?
How to get bookings of a hotel with owner(userid) with using eloquent relationship functions?
Hotel.php
class Hotel extends Model
{
public function userId(){
return $this->belongsTo(User::class,'user_id');
}
public function rooms(){
return $this->hasMany(Room::class,'hotel_id','id');
}
}
Room.php
class Room extends Model
{
public function hotelId(){
return $this->belongsTo(Hotel::class,'hotel_id');
}
public function bookings(){
return $this->hasMany(Booking::class,'room_id','id');
}
}
User.php
class User extends Model
{
public function hotels(){
return $this->hasMany(Hotel::class,'user_id','id');
}
}
Below code add in your respective controller.
$user = \App\User::find(Auth::id());
$hotels = $user->hotels;
foreach ($hotels as $hotel) {
$rooms = $hotel->rooms;
foreach ($rooms as $room) {
print_r($room->bookings);
}
}
Define the relationship with user in model
class Booking extends Model{
/**
* Get the user that owns the booking.
*/
public function owner()
{
return $this->belongsTo(App\User::class,'user_id,'id');
}
}
Then in your controller
$bookings = Booking::with('owner')->all(); // or get() or whatever to get
the booking list
foreach($bookings as $booking){
echo $booking->user->name; // you have access to owner fields
}
Finally i found this.
Booking model
public function room( )
{ return $this->belongsTo('App\room');
}
public function hotel( )
{
return $this->room()->with(['hotel'=> function($query){
$query->with('user');
}]);
}
BookingController
public function owner(Booking $booking ) {
return $booking->with('hotel')->get()
Next thing is Filter with owner

get extra data in Many To Many eloquent-relationships in laravel

I create a table like this:
posts
id title
categories
id name
category_post
post_id
category_id
custom_value
in Category model:
public function posts()
{
return $this->belongsToMany(Post::class);
}
with this command:
$category = Category::find(1);
$posts = $category->posts()->get();
I can get all of posts.
It is possible to return custom_value in category_post with each related post?
Use withPivot function
class Category extends Model
{
public function posts()
{
return $this->belongsToMany(Post::class)->withPivot('custom_value');
}
}
You can use withPivot() method
return $this->belongsToMany(Post::class)
public function posts()
{
return $this->belongsToMany(Post::class)->withPivot('column1','column2');
}
or
public function categories()
{
return $this->belongsToMany(Category::class)->withPivot('column1','column2');
}

Laravel return property from third table

I have three tables:
products
product_types
product_categories
products belongs to product_types and product_types belongs to product_categories.
How can I access a column from product_categories from products?:
ProductTypes model:
class ProductTypes extends Eloquent {
public function category() {
return $this->belongsTo('ProductCategories');
}
}
Products model:
class Product extends Eloquent {
protected $table = 'products';
public function brands() {
return $this->belongsTo('ProductBrands', 'brand_id', 'id');
}
public function ages() {
return $this->belongsTo('ProductAges', 'age_id', 'id');
}
public function types() {
return $this->belongsTo('ProductTypes', 'type_id', 'id');
}
public function images() {
return $this->hasMany('ProductImages');
}
public function reviews() {
return $this->hasMany('ProductReviews');
}
public function toArray() {
$ar = $this->attributes;
$ar['brand'] = $this->brand;
$ar['age'] = $this->age;
$ar['type'] = $this->type;
return $ar;
}
public function getBrandAttribute() {
$brands = $this->brands()->first();
return (isset($brands->brand) ? $brands->brand : '');
}
public function getAgeAttribute() {
$ages = $this->ages()->first();
return (isset($ages->age) ? $ages->age : '');
}
public function getTypeAttribute() {
$types = $this->types()->first();
return (isset($types->type) ? $types->type : '');
}
}
I have tried:
$productData->types()->category()->category
But this gives an error saying the method doesn't exist.
Sorry about the title, couldn't think of one.
The problem is, that you're not executing the query when doing types() and therefore you're calling category() on the query builder instance and not the ProductTypes model.
You can use the dynamic properties for accessing the result of the relationship.
$productData->types->category->category
Also consider renaming your relationships. Currently you have "types" for example but it only returns one type, because its a one-to-many relation. "type" would make more sense.

Get distinct attribute from database in Laravel

I have two tables, one called "products" and another "product_brands".
A product has one brand, and a brand can belong to many products.
I have:
class Product extends Eloquent {
protected $table = 'products';
public function type() {
return $this->hasOne('ProductTypes');
}
public function brand()
{
return $this->hasOne('ProductBrands', 'id', 'brand_id');
}
public function image() {
return $this->hasMany('ProductImages');
}
public function toArray() {
$ar = $this->attributes;
$ar['type'] = $this->type;
$ar['brand'] = $this->brand;
return $ar;
}
public function getBrandAttribute() {
$brand = $this->brand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
}
And my controller:
class ProductsController extends BaseController {
public function index($type_id) {
$Product = new Product;
$products = $Product->where('type_id', $type_id)->get();
return View::make('products.products', array('products' => $products));
}
}
Ideally I would like the column from "product_brands" to be in the same array as the columns from "products", hence why I am trying that stuff with toArray() and getBrandAttribute() but it isn't working.
How can I do this?
I'm sure the getBrandAttribute accessor collides with the brand relationship. Try this instead:
class Product extends Eloquent {
protected $table = 'products';
public function type() {
return $this->hasOne('ProductTypes');
}
public function productBrand() {
return $this->hasOne('ProductBrands', 'id', 'brand_id');
}
public function image() {
return $this->hasMany('ProductImages');
}
public function getBrandAttribute() {
$brand = $this->productBrand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
protected $appends = array('brand'); // this makes Laravel include the property in toArray
}
You should change your accessor to other name:
public function getSpecBrandAttribute() {
$brand = $this->brand()->first();
return (isset($brand->brand) ? $brand->brand : '');
}
and in toArray you should then use:
public function toArray() {
$ar = $this->attributes;
$ar['type'] = $this->type;
$ar['brand'] = $this->spec_brand;
return $ar;
}
That's because you shouldn't create fields with the same name as relationship name.
In addition as it's one to many relationship, probably for brand() you should use belongsTo and not hasOne

Categories