My comment system is working well with polymorphic relation. But i need to explain something clearly to help me to solve this problem first.
There is a brand page and that brand page have comments, also brand has customer support and comments for it. I couldn't mind how to make this relationship with eloquent. Some brands don't have customer support so i need to return boolean to confirm this but i couldn't even prepare database for this relation.
Brand -> customerSupport -> Comments ( How to make this relationship and the database structure )
Do i need to add some extra columns to comments table to do that properly ? Or just need to make new modal as 'CustomerSupport' and import this to commentable_type while adding or listing comments ?
Table Structures
//Brands Table
id - name - slug - img - timestamps
//Comments Table
id - parent_id - user_id(fk) - commentable_id - commentable_type - timestamps
Brand Modal
class Brand extends Model
{
// Table Name
protected $table = 'brands';
// Primary Key
public $primaryKey = 'id';
public function comments()
{
return $this->morphMany('App\Comment', 'commentable')->whereNull('parent_id');
}
}
Comment Modal
class Comment extends Model
{
//Table Name
protected $table = 'comments';
// Primary Key
public $primaryKey = 'id';
//Fillables ...
public function commentable()
{
return $this->morphTo();
}
//Comment belongs to user
public function user()
{
return $this->belongsTo('App\User');
}
//Comment belongs to brand
public function brands()
{
return $this->belongsTo('App\Brand');
}
//Comment have many replies
public function replies()
{
return $this->hasMany('App\Comment', 'parent_id');
}
}
I added a customer_support column to the brand and comments table. With this way, I'm checking if the brand has customer support or not and then get the comments for each brand's customer support. I'm not sure this is the best way to do that relation.
Brand Modal
public function customerSupport()
{
return $this->morphMany('App\Comment', 'commentable')->whereNull('parent_id')
->whereCustomerSupport(true);
}
Related
class Video extends Model
{
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class, CategoryVideo::class, 'video_id','category_id');
}
}
DB::beginTransaction();
$video = Video::find($id);
$video->update($data);
// update categorie count
$items = $video->categories()->get(['category_id', 'video_count']);
foreach ($items as $item){
$item->video_count = Category::where('category_id',$item->category_id)->count();
$item->save();
//$item->update(['video_count' => Category::where('category_id',$item->category_id)->count()]);
}
DB::commit();
save and update have no effect
Ask for help
I want to find out the associated classification through the video, and update the number of videos under the classification
the second parameter in many to many relation is the pivot table model name, not the the pivot model name, so your relation should be like this:
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class, 'category_video', 'video_id','category_id');
}
please replace the second parameter 'category_video' by the name of your pivot table.
you also have to select the primary key in categories when you get Category model instance:
$items = $video->categories()->get(['id','category_id', 'video_count']);
I am using laravel 5.3 and need a bit of help with Eloquent model queries. I have three models (UserDetails, Categories, Articles). I have a relationship between UserDetails->Categories (belongstoMany), and a relationship between Categories->Articles (belongstoMany) which work well. However how would I go about getting the relationship data between Userdetails->Categories->Articles.
Each individual relationship is working fine i.e. Userdetails::find(1)->categories and Categories::find(1)->Articles.
I have a feeling that scopes may be the answer but they don't seem to work when I've attempted it.
Relationships in models
UserDetails.php
public function Categories(){
return $this->belongstoMany('App\Categories', 'users_cats', 'user_id','cat_id');
}
Categories.php
public function articles(){
return $this->belongsToMany('App\Article', 'article_categories', 'categoryID', 'articleID');
}
Ive looked into HasManyThrough function but again, I'm having issues implementing it, as far as I can see it should be
return $this->hasManyThrough('App\Article', 'App\Categories', TertiaryForeignKey, FinalForeignKey, LocalForeignKey);
My tables are set up as
articles_categories pivot table
articleID – primary key of the article
categoryID – primary key of the category
users_cats pivot table
user_id – primary key of the userdetails
cat_id – primary key of the categories
Based on this it the hasManyThrough should look like this?
public function articles(){
return $this->hasManyThrough('App\Article', 'App\Categories', 'user_id', 'articleID', 'id');
}
however this returns the error
Column not found: 1054 Unknown column 'categories.user_id' in 'field list'
update
So if you want to have this kind of relationship
userdetails->categories->articles
then you need to make this:
Userdetail model:
public function categories()
{
return $this->hasMany(Category::class);
}
public function articles()
{
return $this->hasManyThrough(Article::class, Categories::class);
}
Category model:
public function userdetails()
{
return $this->belongsTo(Userdetails::class);
}
public function categories()
{
return $this->hasMany(Category::class);
}
Article model:
public function categories()
{
return $this->belongsToMany(Category::class);
}
Then you can call UserDetails::find(1)->articles->get(); directly
You just need to declare the relationship like this in the
UserDetails.php model:
public function categories()
{
return $this->hasMany(Categories::class);
}
in Categories.php model:
public function articles()
{
return $this->hasMany(Articles::class);
}
Then you can retrieve the collection of categories in your controller:
$userdetails = UserDetails::get();
pass that $categories variable into your View and display each record with an foreach loop (where the articles is the function in your model)
#foreach($userdetails->categories as $usercategories )
<div> {{$usercategories->name}} </div>
#foreach($usercategories->articles as $categoryarticles )
<div> {{$categoryarticles->name}} </div>
#endforeach
#endforeach
with the second foreach you will access the articles of the categories that belongs to the user.
I'm using Laravel as a REST API for a SPA. I have a relationship where families have multiple contributions. The contributions table has a foreign key reference to family's id. I can call on the contributions route with the hasMany/belongsTo set up, and every contribution gets the entire family model it belongs to. But I don't need all that data, I just need a single field from the family table (not the id, but a different field) with each contribution.
Here are my models and resource controller:
class Family extends Eloquent {
protected $table = 'families';
// relationships
public function contributions() {
return $this->hasMany('Contribution');
}
}
class Contribution extends Eloquent {
protected $table = 'contributions';
// relationships
public function family() {
return $this->belongsTo('Family');
}
public function other_field() {
return $this->belongsTo('Family')->select('other_field');
}
}
class ContributionController extends BaseController {
public function index()
{
// works - but returns the entire family with every contribution
$contributions = Contribution::with('family')->get();
// returns other_field == null with every contribution
$contributions = Contribution::with('other_field')->get();
return Response::json($contributions->toArray(),
200);
}
Where am I going wrong with selecting this single field from the belongsTo relationship?
You can use query constraints on the relationship if you use eager loading.
Family::with(['contributions', function($query)
{
$query->select('column');
}])->get();
Im trying to access url property on files table by $post->file->url, but i'm getting "Trying to get property of non-object" error. My table and model is different because i can't use File as model name. is there something missing? I hope someone come with solution. here's my tables:
- posts:
[PK] id
title
[FK] featured_image
- files:
[PK] id
title
url
my model:
class TheFile extends \Eloquent
{
protected $table = 'files';
public function post() {
return $this->belongsTo('Post');
}
}
class Post extends \Eloquent
{
protected $table = 'posts';
public function file() {
return $this->hasOne('TheFile', 'id', 'featured_image');
}
}
thanks in advance.
Maybe I'm wrong but as I see it, you actually have the relationship the wrong way around here. If table X has one table Y then the FK field is on Y and related to the PK on X. But you have it the other way around.
As such you need to do one of two things:
Change your database to put post_id on files rather than having featured_image (points as file`.`id) on posts
Change your relationships to match your database structure:
class TheFile extends \Eloquent
{
protected $table = 'files';
public function post() {
return $this->hasOne('Post');
}
}
class Post extends \Eloquent
{
protected $table = 'posts';
public function file() {
return $this->belongsTo('TheFile');
}
}
Obviously with your various field changes too if you aren't going to change the tables.
The basic rule of thumb is that if a table has the FK it's the 'belongs to' table. The other table is either 'has one' or 'has many'. The slight exception to this rule is obviously 'belongs to many' where a table can relate to another table where neither has an FK - but even that's a specialised version of the same rule - X 'has many' X_Ys and Y 'has many' X_Ys and X_Y belongs to X and X_Y belongs to Y. So it's just syntactic sugar really.
I changed my table name to medias, and my model to Media. Then put these code into Post model . It's works. The name of tables, model and method must be similar.
public function media() {
return $this->belongsTo('Media', 'featured_image', 'id');
}
I have 2 tables, categories(id, name) and products(id, categoryId, title, content) and my models look like this
class Category extends CActiveRecord {
public $id;
public $name;
public function tableName() { return 'categories'; }
public function relations() {
return array('products' => array(self::HAS_MANY, 'Product', 'categoryId'));
}
}
class Product extends CActiveRecord {
public $id;
public $title;
public $content;
public function tableName() { return 'products'; }
}
The problem is when I try to access the products like this
Category::model()->with('products')->findAll()
The relation "products" in active record class "Category" is specified with an invalid foreign key "categoryId". There is no such column in the table "categories".
I looked at the documentation with the User / Post example and don't understand why my example is not working. Can someone clear things up please? Thank you.
Make sure that product table has field called categoryId in order to save the primary key of category table
Try specifing categoryid instead of categoryId. The reason can be in lower_case_table_names mysql directive.