I'm just getting going with Laravel, and have used Eloquent to define my Campaign table. I have a Campaign model which is currently empty.
I'm not sure how to add attributes to this model to represent the fields in the db - or even if I should. The Laravel documentation seems thin on models and searches keep leading me to accessors and mutators.
If I have a database field called platform_type in my campaigns table, how do I link the PlatformType model attribute to this field?
To clarify:
This is not a question about relationships - there is only one entity in my solution thus far.
platform_type is a field in my campaigns table because it is an attribute of a campaign - I'm asking how to represent this in my model.
The model has an internal array which stores the attributes of a given row (it's called $attributes and replicated by $original if you look for them in the source code). The reason it's replicated is so when you call save() it will only do a save if you actually changed them from the originals.
You can access said attributes via $modelInstance->getAttribute("platform_type") or $modelInstance->platform_type which will call the magic __get method that in turn calls the getAttribute
So in your case you can have:
$campaign = Campaign::find($id);
echo $campaign->platform_type;
The ORM will automatically create the relevant SQL query and fill the model instance with the attributes of the row it finds.
You need to define relationships. In the PlatformType model:
public function campaigns()
{
return $this->hasMany(Campaign::class, 'platform_type');
}
And in the Campaign model:
public function platformType()
{
return $this->belongsTo(PlatformType::class, 'platform_type');
}
You also need to rename the campaign table to campaigns. Or you should add this to the model to be able to use a custom name:
protected $table = 'campaign';
At this point, these tables will be connected and relationships will work. However, it is recommended to add foreign key constraints.
Related
Hi I have a table in my database which contains a column with integer values which are actually the primary key of another tabel
Table 1: Details
column : subjects
value : 12,10,1,50,89,88
And another table is subject from where I should fetch the result. I want to know if I can fetch them using my model instead of repeating my code in controller everytime I need to fetch them.
I know you can define relations using
$this->belongsTo()
Or hasMany() depending on circumstances. I want to see If I can use this using scope on Model.
The final result I am looking for is json data returned from table Subject
I would recommend using a polymorphic relationship for this rather than the way you are comma delimiting in a single database table field.
You will have a new record for each association which may seem bad to you at first but it really is worthwhile, work with Eloquent so you don't need to add custom logic to explode those id's and associate manually.
students
id - integer
name - string
subjects
id - integer
name - string
subjectable_id - integer
subjectable_type - string
Then in your models something like this
class Subject extends Model
{
/**
* Get all of the owning subjectable models.
*/
public function subjectable()
{
return $this->morphTo();
}
}
class Student extends Model
{
/**
* Get all of the post's comments.
*/
public function subjects()
{
return $this->morphMany('App\Subject', 'subjectable');
}
}
You can then attach subjects to many different models the same way I demonstrated it attached to Students here.
Edit: If you would like to keep with your same interpretation of how this data is used, you could potentially do this in the Model but it's difficult to say without seeing the logic you are trying not to repeat.
my base class is post
and many submodel such as : video post , image post
all class have specific attribute & inherit parent attrib
& all class need specific behaviors
Problem
when find on post model elequent give super model(post) instance, its wrong
i need instance of submodel
If I understood you correctly, you need relationships
Add a hasMany relationship to your Post.php model:
public function videos()
return $this->hasMany(App\PostVideo::class);
}
As long as your post_video table has a post_id column that references a post, you can call this relationship like this:
foreach($post->videos as $video) {
// Do something
}
And the inverse relationship:
Add a relationship to your PostVideo.php model:
public function post() {
return $this->belongsTo(App\Post::class);
}
And of course, if you have a video, you can access the post it belongs to by doing:
$video->post
It is looked like you want a single table inheritance. In laravel this could be done manually or use package like nanigans or intrip. To use single table inheritance manually, i could suggest you start with reading this stackoverflow question first. However, notice that single table inheritance put everything in a single table but refered by several models that have different behavior. If this is not what you want, just use simple eloquent queries and models - which already explained by Pistachio.
I have the next tables:
pages
id
title
...
dynamic_table_1_infos
id
page_id
image_id
dynamic_field_1
dynamic_field_2
...
dynamic_table_2_infos
...
So there are "one to many" relationships.
Is there any way to use a general approach without creating a DynamicTable[No]Info model "on the fly" for each table?
And what if I will need some extra methods in these models?
The "Page" model will have many relationships with "dynamic_table_[no]_infos" tables. So I will probably need a general method for doing this.
(Has many dynamic_table_1_infos / has many dynamic_table_2_infos ...)
What I am trying to do is somehow inspired by Dupal`s content types.
If you want to save a single model data to multiple tables depending on the value of some model attribute, you'll need to override model's getTable() method to return the name of the table it should write to.
I'm not sure how you want to decide to which table Eloquent should save to - for example, if you had an attribute called segment in your mode, you could just do:
public function getTable() {
return 'dynamic_table_' . $this->segment . '_infos';
}
I'm trying to get my head around using polymorphic relationships for a many-to-many relationship between suppliers and products:
products
id
name
suppliers
id
name
product_supplier
id
product_id // belongsToMany easily takes care of this id
supplier_id // and this id
price // this can be fetched using withPivot('price')
deliverymethod_id // I'm having difficulties "joining" this one.
I'm confident in using belongsToMany(), I can easily do something like this:
public function products()
{
return $this
->belongsToMany('Supplier')
->withPivot('price');
}
But the catch here is joining to that third column in the relationship table:
deliverymethods
id
name
I am unsure how to do this. I've been told that Polymorphic Relationships are what I'm after however I'm unsure how to implement them for my situation.
http://laravel.com/docs/4.2/eloquent#many-to-many-polymorphic-relations
According to the documentation, I would have to rename my table columns to include *able_id and *able_type. This is really confusing.
I was expecting laravel to having something like belongsToMany('Supplier')->withAlso('Deliverymethod')
I'm afraid that method does not exist (yet?).
What I fall back to is manually filling in the 3rd relation:
public function products()
{
return $this
->belongsToMany('Supplier')
->withPivot('price', 'delivermethod_id');
}
Now I can access ->pivot->deliverymethod_id on every Product that I get via Supplier.
You could even add a function in your Product model that fills this in automatically:
Class Product ... {
protected $appends = array('deliverymethod');
public function getDeliverymethodAttribute()
{
return Deliverymethod::find($this->pivot->delivermethod_id);
}
Now every time you request a product via it's relation to the supplier, it automatically includes a deliverymethod attribute with the object in it.
(To have it not throw an error when you get a Product directly, just remove the $appends variable from the Product model and call the getDeliverymethodAttribute() method manually whenever you need it.)
Short explanation about polymorphic relations:
Polymorphic relations are for relations, where two models are related to a third model at the same time. So for example both a User and a Product can have a Picture of them. Now, it doesn't make sense to have two models for the pictures (UserPicture and ProductPicture), since they both have the same characteristics. This would be a perfect reason to use a polymorphic relation, where the Picture can both belong to a User or a Product.
However, in your case the Deliverymethod applies directly to the relation between Supplier and Product. So this is not where polymorphic relations would work, but it has instead to be done the way you did it.
I'm a Symfony 2 developper who's beginning on Laravel. I'm a little bit lost with Laravel's ORM, it seems that we have to directly deal with the database to create tables manually... On Symfony, this was automatically made by Doctrine according to the mapping classes (and #ORM annotations).
Is the concept totally different on Laravel, or did I just not find the way to do it like on Symfony ?
Your question is not clear enough but I guess you want to know how Eloquent models map tables, in this case you have to use your table names (in database) the plural form of the word (but not mandatory), for example, a table that used to contain user data should be users or for post data the table should be posts but you may use whatever you want.
To map the users table with an Eloquent model; all you need to do i; create a model like this:
Post extends Eloquent {
//...
}
Now you may use something like this:
$posts = Post::all();
$post = Post::find(1);
Laravel will query from the posts table but if your table name is different than the standard way Laravel wants then you have to tell Laravel what is the table name by adding a property in the model, for example:
Post extends Eloquent {
protected $table = 'article'; // Laravel will query from article table
//...
}
You can use Post model as;
// Laravel will query from article table in the database
// because you gave the $table property with the table name
$posts = Post::all();
$post = Post::find(1);
Read more on the manual.
Laravel have migration like DoctrineMigrationsBundle, so in your model(entitie) you just write (for exemple):
class YourClass extends Eloquent {
}
So no need to overcharge your model with attribute, laravel do it automatically
http://laravel.com/docs/migrations for more information aboutmigration