I have three models as following:
-comments
-item that hasMany comments
-list that hasMany items & hasManyThrough('comment','item)
which means i have lists with many items and items with many comments.the comments are linked to lists via hasManyThrough items.
lists are as follows:
class List extends Model{
protected $fillable = ['title','description','user_id'];
public function items()
{
return $this->hasMany('App\Item');
}
public function comment()
{
return $this->hasManyThrough('App\Comment', 'App\Item');
}}
items:
class Item extends Model
{
//
protected $guarded = [];
protected $fillable = ['title','description','user_id','list_id'];
public function comment(){
return $this->hasMany('App\Comment');
}
public function list(){
return $this->belongsTo('App\List');
}
}
and comments:
class Comment extends Model
{
//
protected $fillable = ['content','item_id','user_id'];
public function items(){
return $this->belongsTo('App\Item');
}
}
How can i access the comments relating to each list?
EDIT: when i try to access the comments for a list with id=15 e.g. $list->comments , i get the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'items.list_id' in 'field list' (SQL: select comments.*, items.list_id as laravel_through_key from comments inner join items on items.id = comments.item_id where items.list_id = 15)
Related
The tables category, category_description and descriptions are related:
public function descriptions(): BelongsToMany
{
return $this->belongsToMany(Description::class);
}
public function categories(): BelongsTo {
return $this->belongsTo(Category::class);
}
public function descriptions(): BelongsTo {
return $this->belongsTo(Description::class);
}
public function descriptions(): BelongsToMany
{
return $this->belongsToMany(Category::class);
}
in Model respectively. When saving or updating:
public function createOrUpdate(Category $category, Request $request)
{
$category->fill($request->get('category'))->save();
$category->descriptions()->syncWithoutDetaching(
$request->input('category.descriptions', [])
);
}
An error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'description' in 'field list' (SQL: insert into `category_description` (`category_id`, `description`, `description_id`, `is_active`, `meta-description`, `meta-h1`, `meta-keyword`, `meta-title`, `name`, `slug`) values (1, 41231231, 0, 1, 23, 124, 12, 12, 12333312, 74))
Perhaps I missed something somewhere, since there is not so much experience.
UPDATE:
a category can have multiple entries, but the description has only one parent. Rewrote — One To Many (Polymorphic):
public function descriptions()
{
return $this->morphMany(Description::class, 'descriptable');
}
public function descriptable()
{
return $this->morphTo();
}
There are no problems with saving 1 record, but how to update several records at the same time?
How about?
// Category Model.
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public function descriptions()
{
return $this->belongsToMany(Description::class)
->using(CategoryDescription::class);
}
}
// Description Model.
use Illuminate\Database\Eloquent\Model;
class Description extends Model
{
protected $fillable = [
"name",
"description",
"meta-title",
"meta-description",
"meta-keyword",
"meta-h1",
"slug",
"is_active",
];
public function categories()
{
return $this->belongsToMany(Category::class)
->using(CategoryDescription::class);
}
}
// Intermediate Model.
use Illuminate\Database\Eloquent\Relations\Pivot;
class CategoryDescription extends Pivot
{
protected $table = "category_description";
public $incrementing = true;
public function category()
{
return $this->belongsTo(Category::class, "category_id", "id");
}
public function description()
{
return $this->belongsTo(Description::class, "description_id", "id");
}
}
// createOrUpdate method.
public function createOrUpdate(Category $category, Request $request)
{
$category->fill($request->get('category'))->save();
$description = Description::create(
Arr::collapse($request->input('category.descriptions', []))
);
$category->descriptions()->syncWithoutDetaching(
$description->id
);
}
Notes:
Much as this may work for you, I personally think that you don't have a many-to-many relationship here. I believe a one-to-many relationship is sufficient.
The problem is you send data to be inserted in columns that are not found
You should send only the data that you need to insert in the table
so in your case, you should write your function as
$category->descriptions()->syncWithoutDetaching($description_id); // the id of the description you want to attach with this category
If you still don't have the description yet in the database and you are creating it with the same request you can do something like this
Description::create(['columnName'=>$request->get('columnName'),'columnName2'=>$request->get('columnName2')])->id
I have four tables that are having relationships form the first to the last where
users is a parent to village on applicant_id , Village to Cell on village_id , Cell to Sector on cell_id
and my eloquent query is as follows and it works perfectly without a where clause, when where clause is added I get an error:
Column not found: 1054 Unknown column 'applicant_id' in 'where clause'
// joins users , village ,cell and sector
$uvcsector = SectorApproval::with('Cell.Village.UserApplicant')
->where('applicant_id', 10)
-> get();
Models :
class Users extends Model
{
protected $table ="users";
public function VillageApplicant(){
return $this->hasMany(VillageApproval::class);
}
}
class VillageApproval extends Model
{
protected $table ="villageapplication";
// OnetoOne relationship inverse
public function UserApplicant()
{
return $this->belongsTo(Users::class, 'applicant_id');
}
// One Village application can be sent in one cell (OnetoOne)
public function Cell(){
return $this->hasOne(CellApproval::class);
}
}
class CellApproval extends Model
{
protected $table ="cellapplication";
// OnetoOne relationship inverse
public function Village()
{
return $this->belongsTo(VillageApproval::class, 'village_id');
}
// One Cell application can be sent in one sector (OnetoOne)
public function Sector(){
return $this->hasOne(SectorApproval::class);
}
}
class SectorApproval extends Model
{
protected $table ="sectorapplication";
// OnetoOne relationship inverse
public function Cell()
{
return $this->belongsTo(CellApproval::class, 'cell_id');
}
}
Use whereHas to search in the related tables.
$uvcsector = SectorApproval::with('Cell.Village.UserApplicant')
->whereHas('Cell.Village.UserApplicant', function($query) use ($id){
$query->where('applicant_id', $id);
})
-> get();
->where('village.application_id', 10)
i have three database tables
category (id,name)
subcategory (id,name,category_id) foreign_key category_id on table category(id).
subject(id,name,subcategory_id) foreign_key subcategory_id on table subcategory (id).
i want a row containing the following -
subject_id subject_name category_name subcategory_id
how to do this using eloquent .and if approach is wrong .please suggest a good method to achieve the same .
Assuming you have the following models:
// Category Model
class Category extends \Eloquent {
protected $table = "category";
public function subcategory(){
$this->hasMany('Subcategory','category_id');
}
}
// Subcategory Model
class Subcategory extends \Eloquent {
protected $table = "subcategory";
public function category(){
$this->belongsTo('Category', 'category_id');
}
pubic function subject(){
$this->hasMany('Subject', 'subcategory_id');
}
}
// Subject model
class Subject extends \Eloquent {
protected $table = "subject";
public function subcategory(){
$this->belongsTo('Subcategory','subcategory_id');
}
}
You can get the data in your controller as follows:
// for subject with id 1
public function getOneRow(){
$subject = Subject::with('subcategory.category')->findOrFail(1);
//subject_id = $subject->id
//subject_name = $subject->name
//subcategory_id = $subject->subcategory->id
//category_name = $subject->subcategory->category->name
return array("subject_name"=>$subject->name, "category_name"=>$subject->subcategory->id, "subcategory_name"=>$subject->subcategory->category->name);
}
// for all subjects
public function getOneRow(){
$subjects = Subject::with('subcategory.category')->all();
$out = array();
foreach($subjects as $subject){
// each row
//subject_id = $subject->id
//subject_name = $subject->name
//subcategory_id = $subject->subcategory->id
//category_name = $subject->subcategory->category->name
$out[] = array("subject_name"=>$subject->name, "category_name"=>$subject->subcategory->id, "subcategory_name"=>$subject->subcategory->category->name);
}
return $out;
}
Edit for Laravel 5.1
Your models will be defined differently. Here's an example. Or follow the docs:
// Category Model Laravel 5.1
use Illuminate\Database\Eloquent\Model;
class Category extends Model {
protected $table = "category";
public function subcategory(){
$this->hasMany('Subcategory','category_id');
}
}
Edit: Completed the functions with return statements as requested in comment
I am trying to do a single query to get back an order and the card to charge, but getting an error.
Card model:
class Card extends Eloquent {
protected $guarded = array();
public static $rules = array();
public function user()
{
return $this->belongsTo('User');
}
public function orders()
{
return $this->hasMany('Order');
}
}
Order model:
class Order extends Eloquent {
protected $guarded = array();
public static $rules = array();
public function user()
{
return $this->belongsTo('User');
}
public function card()
{
return $this->hasOne('Card');
}
public function address()
{
return $this->belongsTo('Address');
}
public function orderItems()
{
return $this->hasMany('OrderItem');
}
}
What I am trying to get back:
$order = Order::with('card')->find($id);
This obviously doesn't work and I have tried several combos. I think the issue is with my models/relationships.
Any idea how I can get back the order with the card/token details?
DB info: Each order can have only one card_id and each card can be in many orders. There is no order_id in the card.
Orders table basically:
id | card_id
Cards table:
id | token
Trying to get the token col to return with the Order.
In your Order model, you need to change this:
public function card()
{
return $this->hasOne('Card');
}
to this:
public function card()
{
return $this->belongsTo('Card');
}
The reason is that you are defining the inverse of the hasMany relationship. With the belongsTo relationship, Eloquent will look for a card_id column on the orders table.
I want to populate Every CustomerEvent with the Customer related to the CustomerEvent.
When I Loop through the object and call to $customerevent->customer foreach object I can get the customer related to that event but Can I populate the all objects in the main object without looping through every single event ?
I want to do something like this:
$typeOne = CustomerEvent::typeOne()->get();
$customersWithTypeOne = $typeOne->Customers;
Here my code:
Table 1: "events"
id, customer_id
Model for Table 1 "CustomerEvent":
<?php
class CustomerEvent extends Eloquent{
protected $guarded = ['id'];
public $table = "event";
protected $softDelete = true;
public function scopeTypeOne($query)
{
$followUps = $query->where('type_id', '=', '1');
}
public function Customers()
{
return $this->belongsTo('Customer', 'customer_id');
}
}
Table 2: "customers"
id
Model for Table 2 "Customers":
<?php class Customer extends BaseModel{
protected $guarded = ['id'];
}
EventController:
public function index()
{
$typeOne = CustomerEvent::typeOne()->get();
$customersWithTypeOne = $typeOne->Customers;
dd($customersWithTypeOne);
}
From you database scheme I see customer has many events, so I would recommend to define this relationship in you Customer model.
class Customer extends BaseModel{
protected $guarded = ['id'];
public function events()
{
return $this->hasMany('CustomerEvent', 'customer_id');
}
}
Then you will be able to query customers with events:
$customersWithTypeOne = Customer::whereHas('events', function($query){
$query->where('type_id', 1);
})->get()
Maybe Ardent can help you: https://github.com/laravelbook/ardent
It's an extension for Eloquent models and very popular.