Laravel 4 Eloquent one-to-many relations with morph - php

I'm pretty new to Laravel and Eloquent, so this could easily be something trivial but anyways I've been missing a good solution so far. So heres my problem:
I have a main gallery and i want the user to be able to upload any images or videos that he needs into that main gallery and select images/videos from that gallery to be shown elsewhere on the website (basically what i'm doing is centralising multimedia content all in one place).
Using deduction (with all my poor knowledge of Eloquent) i found this as best solution for me:
//Gallery Model
class Gallery extends Eloquent {
protected $table = 'gallery';
protected $guarded = array();
public static $rules = array();
public function images() {
return $this->morphMany('Image', 'imageable');
}
public function videos() {
return $this->morphMany('Video', 'videoable');
}
}
//About Orchestra Model
class OrchestraAbout extends Eloquent {
protected $table = 'orchestra_about';
protected $guarded = array();
public static $rules = array();
public function images() {
return $this->morphMany('Image', 'imageable');
}
public function videos() {
return $this->morphMany('Video', 'videoable');
}
}
//Image Model
class Image extends Eloquent {
protected $guarded = array();
public static $rules = array();
public function imageable()
{
return $this->morphTo();
}
}
//Video Model
class Video extends Eloquent {
protected $guarded = array();
public static $rules = array();
public function videoable()
{
return $this->morphTo();
}
}
And when inserting into database i simply duplicate the row and only change the imageable_id /videoable_id and imageable_type/videoable_type to match the OrchestraAbout Model.
Anyone here knows of a better solution for this?
Thanks for all the smart answers! Cheers!

Related

Laravel - using inRandomOrder() on belongsToMany RelationShips

in this code as:
$latestHerbsInformation = \App\ContentCategories::find('14')->contents->take(5);
which that work fine i want to use inRandomOrder() to get random rows from contents, Contents and ContentCategories are belongsToMany RelationShips and this code:
$latestHerbsInformation = \App\ContentCategories::find('14')->contents->inRandomOrder()->take(5);
don't work for me.
Contents model:
class Contents extends Model
{
use Sluggable;
protected $table = 'contents';
protected $guarded = ['id'];
public function categories()
{
return $this->belongsToMany(ContentCategories::class);
}
}
ContentCategories model:
class ContentCategories extends Model
{
protected $table = 'contents_categories';
protected $guarded = ['id'];
public function contents()
{
return $this->belongsToMany(Contents::class);
}
}
i get this error:
Method inRandomOrder does not exist.
how can i solve this problem? Thanks in advance
The correct query is:
\App\ContentCategories::find('14')->contents()->inRandomOrder()->take(5)->get();
Because this will execute the query and will return a collection:
\App\ContentCategories::find('14')->contents

associative table for OneToMany relation

I'm working on a subtitles bot where:
A Movie has multiple subtitles (depending on quality and language)
A Series has multiple seasons with multiple episodes that have multiple subtitles (same as a movie)
These are my tables (Thanks to DaveRandom):
The problem is, as far as I know associative tables are for many-to-many relationships (correct me if I'm wrong), I'm kinda stuck here, especially with Eloquent's belongsToMany method:
class Subtitle extends Model {
public $guarded = [];
public $timestamps = false;
public function SeriesEpisodes()
{
return $this->belongsToMany('SeriesEpisode', null, null, 'series_episodes_subtitle');
}
public function Movie()
{
return $this->belongsToMany('Movie');
}
}
But the problem is, A Subtitle belongsToOne Episode, whereas an Episode might have many subtitles.
I was wondering how one could use associative tables for such structure.
Or should I change the structure?
So what I was trying to achieve is possible with polymorphic relationships,
2 associative tables are removed and instead 2 fields are added to subtitles table:
ex: parent_type, parent_id
then I can use:
subtitles:
class Subtitle extends Model {
public $guarded = [];
public $timestamps = false;
public function Parent()
{
return $this->morphTo();
}
}
series_episodes:
class SeriesEpisode extends Model {
public $timestamps = false;
public $guarded = [];
public function Subtitles()
{
return $this->morphMany('Subtitle', 'Owner');
}
}
movies:
class Movie extends Model {
public $timestamps = false;
public $guarded = [];
public function Subtitles()
{
return $this->morphMany('Subtitle', 'Owner');
}
}
Hope it helps others.

How to insert data using relation?

I have two table
posts
id|post_title|post_content
post_images
id|images|post_id
Controller
public function AddPost(Request $request)
{
Post::create($request->all());
// PostImage::create();
return Redirect::to('Post');
}
Also i have added Relation
class Post extends Model
{
protected $table = 'posts';
public function images()
{
return $this->hasMany('App\PostImage');
}
}
class PostImage extends Model
{
public function post()
{
return $this->belongsTo('App\Post');
}
}
I have one form where i adding post title ,post content and selecting multiple images. My question is how I can store post images along with post id in post_images table?
Rewrite your code like this
class Post extends Model
{
protected $table = 'posts';
//add $fillable here
protected $fillable = ['post_title', 'post_content'];
public function images()
{
return $this->hasMany(App\PostImage::class);
}
}
class PostImage extends Model
{
protected $table = 'post_images';
//add $fillable here
protected $fillable = ['images', 'post_id'];
public function post()
{
return $this->belongsTo(App\Post::class);
}
}
Now in your controller
Post::create($request->all())->images()->create($request->all());
Here Post create saves your data to db also returns the object then
you accesses the relation images and saves data to images.
See here for more details One To Many

Eloquent ORM Movie Location

I am using Laravel 4 and eloquent orm to build a movie session database.
Now I have the following Models.
class Location extends \Eloquent
{
public $timestamps = false;
public $table = 'movsys_location';
protected $fillable = array('name', 'desc');
public function sessions(){
return $this->hasMany('Session', 'location_id');
}
}
class Session extends \Eloquent
{
public $timestamps = false;
public $table = 'movsys_session';
protected $fillable = array('time');
public function location(){
return $this->hasOne('Location', 'id');
}
}
(Note: These models are stripped to the necessary code.)
Now in my controller, I have the following.
$Sessions = Session::all();
foreach($Sessions as $Session){
echo (isset($Session->location->name) ? $Session->location->name : 'NO LOCATION');
}
And this is what my database looks like:
Now, everything seems to work, but even though both sessions have the same location, ONLY the first session will return the name of the location! The second echo will return "NO LOCATION".
Any idea or help as to why would be appreciated. If this answer isnt clear enough let me know.
Try this one in place of yours:
class Session extends \Eloquent
{
public $timestamps = false;
public $table = 'movsys_session';
protected $fillable = array('time');
public function location(){
return $this->belongsTo('Location');
}
}

Eloquent model relationship returning as null

I have a laravel model
class Project extends Eloquent {
public static $timestamps = true;
public $includes = array('members','members.memberdata');
public function tasks() {
return $this->has_many('Usertask','project_id');
}
public function members() {
return $this->has_many('Projectmember','project_id');
}
}
and a related models
class Projectmember extends Eloquent {
public static $table = "project_members";
public static $timestamps = true;
public function project() {
return $this->belongs_to('Project');
}
public function memberdata() {
return $this->has_one('Usermetadata','user_id');
}
}
class Usermetadata extends Eloquent {
public static $table = "users_metadata";
public function user() {
return $this->belongs_to('User');
}
public function member() {
return $this->belongs_to('Projectmember','user_id');
}
}
When i attempt to retrieve a single project model like so
$project = Project::find($id);
return Response::eloquent($project);
my json output looks like this
{"id":1,"user_id":1,"name":"UberWork","description":"Web based project management \/ task management app","target_date":"2013-11-15 00:00:00","budget":null,"status":0,"created_at":"2013-04-16 20:13:59","updated_at":"2013-04-16 20:13:59","members":[{"id":1,"project_id":1,"user_id":1,"created_at":"2013-04-16 20:13:59","updated_at":"2013-04-16 20:13:59","memberdata":{"user_id":1,"first_name":"Tamarakuro","last_name":"Foh","photo":"","company_name":null,"phone":null,"package":"free","subscription_start":"0000-00-00 00:00:00","subscription_end":"0000-00-00 00:00:00","api_key":"12b14a7d3ca48c53bb5b1a88fa3eca3b"}},{"id":3,"project_id":1,"user_id":3,"created_at":"2013-04-16 20:13:59","updated_at":"2013-04-16 20:13:59","memberdata":{"user_id":3,"first_name":"Ebere","last_name":"Uche","photo":"","company_name":"Chronotech Labs","phone":null,"package":"free","subscription_start":"0000-00-00 00:00:00","subscription_end":"0000-00-00 00:00:00","api_key":"ab446bd9ffbb898e818a892c7401e0f6"}},{"id":4,"project_id":1,"user_id":2,"created_at":"2013-04-17 08:13:00","updated_at":"2013-04-17 08:13:00","memberdata":null}]}
My database look like this;
Users
id
email
password
ip_address
active
...
users_metadata
id
user_id
first_name
last_name
profile_photo
...
Projects
id
user_id
name
description
status
...
project_members
id
project_id
user_id
My question is why is the last member of the project having its memberdata as "null", while the others are not null. Am i doing something wrong?
Relationships in Eloquent always link a primary key (pk) with a foreign key (fk). However, you're trying to base a relationship on two foreign keys, skipping out a relationship. The only Eloquent solution is to include the extra relationship step. Here are some models (I've ommited the relationships we don't need for this example)...
class Project extends Eloquent {
public static $timestamps = true;
public $includes = array('members','members.user', 'members.user.metadata');
public function members()
{
return $this->has_many('Projectmember','project_id');
}
}
class Projectmember extends Eloquent {
public static $table = "project_members";
public static $timestamps = true;
public function user()
{
return $this->belongs_to('User');
}
}
class User extends Eloquent {
public static $timestamps = true;
public $hidden = array('password', 'ip_address');
public function metadata()
{
return $this->has_one('Usermetadata');
}
}
class Usermetadata extends Eloquent {
public static $table = "users_metadata";
public function user() {
return $this->belongs_to('User');
}
}
I can see why you'd want to skip the relationship, but sadly it's not possible with relationships.

Categories