I got 3 linked tables and i am quite lost with eloquent relationship.
I need help to recognize my relationship type. I use Laravel 4.1
acquisitions table :
#id
date
sensors table :
#id
name
acquisition_sensor table:
#id
acquisition_id
sensor_id
depth
value
Indeed 1 acquisition may have many depth, and different values.
I search a way to link my tables and use sensor model likee:
Sensor::find(1)->acquisitions->count();
and
Sensor::find(1)->sensor_acquisition->get();
I actually do it with the Query Builder but i think there is a way to use it more efficiently with eloquent !
You are going to want to set up a many-to-many relationship in your Eloquent models.
Sensor.php (model)
public function acquisitions()
{
return $this->belongsToMany('Acquisition', 'acquisition_sensor', 'acquisition_id', 'sensor_id');
}
Acquisition.php (modal)
public function sensors()
{
return $this->belongsToMany('Sensor', 'acquisition_sensor', 'acquisition_id', 'sensor_id');
}
You can read more about many-to-many Eloquent relationships here, http://laravel.com/docs/eloquent#many-to-many
If you want to run the eloquent query you described in your question, then you can do it like so:
Sensor::find(1)->acquisitions()->count();
If you are chaining, then make sure to add the () to acquisitions.
Related
I'm very much a beginner when it comes to database relationships hence what I suspect is a basic question! I have two database tables as follows:
Projects
id
company_id
name
etc...
rfis
id
project_id (foreign key is id on the Projects table above)
Number (this is the column I need help with - more below)
question
The relationships at the Model level for these tables are as follows:
Project
public function rfi()
{
return $this->hasMany('App\Rfi');
}
RFI
public function project()
{
return $this->belongsTo('App\Project');
}
What I'm trying to achieve
In the RFI table I need a system generated number or essentially a count of RFI's. Where I'm finding the difficulty is that I need the RFI number/count to start again for each project. To clarify, please see the RFI table below which I have manually created with the the 'number' how I would like it displayed (notice it resets for each new project and the count starts from there).
Any assistance would be much appreciated!
Todd
So the number field depends on the number of project_id in the RFI table. It is exactly the number of rows with project_id plus one.
So when you want to insert a new row, you calculate number based on project_id and assign it.
RFI::create([
'project_id' => $project_id,
'number' => RFI::where('project_id', $project_id)->count() + 1,
...
]);
What I understood is that you want to set the value of the "number" field to "1" if it's a new project and "increment" if it's an existing project. And you want to automate this without checking for it every time you save a new row for "RFI" table.
What you need is a mutator. It's basically a method that you will write inside the desired Model class and there you will write your own logic for saving data. Laravel will run that function automatically every time you save something. Here you will learn more about mutators.
Use this method inside the "RFI" model class.
public function setNumberAttribute($value)
{
if(this is new project)
$this->attributes['number'] = 1;
else
$this->attributes['number']++;
}
Bonus topic: while talking about mutators, there's also another type of method called accessor. It does the same thing as mutators do, but just the opposite. Mutators get called while saving data, accessors get called while fetching data.
I am creating a Laravel Application with Eloquent connected to MySQL DBMS where I have three models:
Product
ProductGallery
File
I have also the following relations
One Product has one ProductGallery
One ProductGallery has many File
My question is:
Is it okay if I store images in ProductGallery as an array of file_ids
instead of creating a join table or having gallery_id in File model?
public function setImagesAttribute($images)
{
$this->attributes['images'] = serialize($images);
}
public function getImagesAttribute()
{
if (empty($this->attributes['images']) || is_null($this->attributes['images'])) return [];
return unserialize($this->attributes['images']);
}
I am asking this question to know if there is any side effects for this method
and in the future there might be other models related to File model (Category may have featured image file and so on).
In my opinion Better Option is creating a pivot table.. Because further when you have to join , you pull the array and you have to execute a query under a loop that is bad..
I have this setup as my database structure which already works pretty well, but I feel like it could be better, but cannot figure out how.
Database Structure:-
Events can have multiple sub-events. Users can join these events and optionally their sub-events. With this structure I have all constraints, but the one that links the event attending with the sub event attendings => there can be sub event attendings left without having the main event attending (this shouldn't be possible as users who don't attend the main event cannot attend it's sub events).
I am currently working with Laravel so it looks like this:
User:
hasMany Event (as organizer of these events)
belongsToMany EventAttending (which events is a user joining)
belongsToMany SubEventAttending (which sub-events is a user joining)
Event:
belongsTo User
hasMany SubEvent
belongsToMany EventAttending (which users are attending this event)
SubEvent:
belongsTo Event
belongsToMany SubEventAttending (which users are attending this sub-event)
The problem arises when trying to manage the sub-event attendings of a user. How would I make this constraint between the event and sub-event attendings exist, while keeping it clean with the capabilities of Laravel / What can you give as advice for a better structuring / How would you guys do it?
Edit
To clarify, the events and sub-events store different things, have different properties. Also I need to store information for the event attendings (like did he attend in real life) and sub-event attendings, most likely differing ones.
Edit
Edward Haber has the better structure, but as my two pivot tables (the connection between User-Event and User-SubEvent) store additional diferent type of information, currently chose to remain with the initial design.
One of the biggest problems I am facing (which does exist with both structure) is querying for a User while getting the attended Events with the attended SubEvents. Trying to achive this result:
User[]:{
...,
attending_events[]:{
...,
attending_sub_events[]:{
...
}
}
}
Been thinking for hours for a clean solution, couldn't get anything else to work. Wouldn't like to write the whole SQL query manually. My current implementation with the two pivot table looks like this (result not nested, code messy):
$users = User::withCount(['attendingEvents' => function($query) use($eventId){
$query->where('event_id', $eventId);
}])
->with(['attendingSubEvents' => function($query) use($eventId){
$query->select('id')->whereHas('event', function($query) use($eventId){
$query->where('id', $eventId);
});
}]);
With this approach I get the sub-events separated from the main event. (querying only for the main attending-event count, because I only need to determine whether he is joining or not).
The pattern for this type of solution is to use a Polymorphic Relationship. This solution focuses just on connecting the User to the Event and SubEvent - the rest of the relations look correct.
<?php
class User extends Model {
public function attending() {
return $this->morphTo();
}
}
<?php
class Event extends Model {
public function attendees() {
return $this->morphMany('App\User', 'attending')
}
}
<?php
class Subevent extends Model {
public function attendees() {
return $this->morphMany('App\User', 'attending')
}
}
The users table needs these fields:
*users*
-----
id
attending_id
attending_type
This is all untested - but the basic idea. (Edited: changed name of polymorphic method to attending from attendee)
I am using struts2 , hibernate and MySql for my project.
I have table name TimeTable having 42 columns (all long datatype) containing course codes.
I want to search "column names" having particular course code from a particular row.
Help me please.
If you have mapped the entity in a "proper" way in hibernate, the answer is obvious:
You will have an entity called TimeTable, which have 42 relationships to Course (I bet the attribute name will be course1, course2.... course42).
The resulting HQL is simply a bunch of OR
from TimeTable t
where t.course1.code = :something
OR t.course2.code = :something .....
However, it is obviously a bad model design. You should make Timetable and Course a Many-To-Many relationship, and have another table storing the relationship. So, in the entity, you will see something like
class TimeTable {
#ManyToMany
private List<Course> courses;
}
Your life will be much easier with such design.
I have two entities, Account and Subscription with a many-to-many association between them. I can't seem to find in the tutorials anywhere how to do the following:
I want to find all the Accounts with a Subscription of type x. If I wasn't using the Entity framework I could join to the AccountSubscription table, but that isn't accessible via Entity. Do I have to create a special entity if I need to query on a many-to-many relationship?
EF should create a navigation property for a many-to-many relationship. Then you should be able to do something like this:
var accounts = from a in Accounts
where a.Subscriptions.Any(s => s.SubscriptionType == "something")
select a;
For example, I have a simple db with a many to many relationship between Products and Groups:
And EF creates the association in the model:
So I can create a query like this (here including the Groups so I can see the Category):
What about something like this:
List<Accounts> myAccounts = //get accounts;
foreach(Accounts a in myAccounts)
{
foreach(Subscriptions s in a)
{
//add it to a global list?
}
}