When I want to query for all states a specific dispatch ticket in my database, I would do it like this:
public function test() {
$dispatches = Dispatch::where('dispatch_reference', '=', 'dis_548k14s4glnhv5')->get();
foreach($dispatches->states as $state) {
var_dump($state);
}
}
But this throws an error message, that states is not being recognized. The models I created are:
Dispatch
class Dispatch extends Model {
use EventGenerator;
protected $table = 'dispatches';
protected $fillable = ['dispatch_reference', 'incident_reference', 'state'];
public $timestamps = true;
// Since the FK exists in this table, the belongsTo() method is used to state that the dispatch model is related to an address.
// Dispatch __belongs_to__ Incident
public function incident() {
return $this->belongsTo('App\Classes\Incident');
}
// Dispatch __belongs_to_many__ State
public function states() {
return $this->belongsToMany('App\Classes\DispatchState')->withTimestamps();
}
public function attachDispatchState($id) {
$this->states()->attach($id);
$this->touch();
}
// set fields on the eloquent object and save to database
// raise event that the incident was created.
public function createDispatch($command) {
// Get BodyContent from POST Request
$this->dispatchReference = $command->dispatchReference;
$this->incidentReference = $command->incidentReference;
// Create new Dispatch
$dispatch = Dispatch::create(array(
'dispatch_reference' => $this->dispatchReference,
'incident_reference' => $this->incidentReference
));
$dispatchState = DispatchState::where('state', '=', 'processing')->first();
$dispatch->attachDispatchState($dispatchState->id);
return $this;
}
Dispatch State
class DispatchState extends Model {
use EventGenerator;
// Define Table Setup with fillabe fields
protected $table = 'dispatch_states';
// Fillable fields in database
protected $fillable = ['state'];
// include timestamps
public $timestamps = true;
// Status __belongs_to_many__ Dispatches
public function dispatches() {
return $this->belongsToMany('App\Classes\Dispatch');
}
}
I would expect to see all the different states attached to one dispatch as i am using a pivot table that works fine so far. I just cannot query the results. Do I have an error in my models?
When you're calling get() you're getting a collection of Dispatch object. If you expect to only get a single object (e.g. when dispatch reference is unique), call first() instead of get():
$dispatch = Dispatch::where('dispatch_reference', '=', 'dis_548k14s4glnhv5')->first();
If, however, dispatch reference is not unique, you'll need to first iterate through collection of dispatches and then through their related states:
$dispatches = Dispatch::where('dispatch_reference', '=', 'dis_548k14s4glnhv5')->get();
foreach($dispatches as $dispatch) {
foreach ($dispatch->states as $state) {
var_dump($state);
}
}
Related
i trying to load all rows from a model without the relationship.
The attributes $with it not event set on my Event model but when i do
$events = Event::all();
all my relationship are loaded, and i can see all the query with the dbquerylog.
i don't understand why theses relationship are loaded,
Please help me !
Thanks you.
I'm using Laravel 8.
here's an example.
class Event extends Model {
public function items() {
return $this->hasMany(Item::class);
}
public function items2() {
return $this->hasMany(Item2::class);
}
public function items3() {
return $this->hasMany(Item3::class);
}
public function items4() {
return $this->hasOne(Item4::class);
}
}
$events = Event::all();
If you have a single instance of a model object, you can do:
$obj->withoutRelations();
As laravel documentations says you can use without: https://laravel.com/docs/8.x/eloquent-relationships
Model
protected $with = ['item1','item2','item3','item4'];
Controller
$events = Event::without(['item1','item2','item3','item4'])->get();
I met this problem one day, and it turned out that I was using relation in scope method. Because of this relation values were added to response.
Check out this example:
class Event extends Model {
public function items() {
return $this->hasMany(Item::class);
}
[...]
public function scopeItemsGreen() {
return $this->items->every(function ($item) {
return $item->color == 'green';
});
}
I'm trying to retrieve data from two tables with relationship one-to-many. I need it to return in one response since it will be displayed simultaneously. However, I don't understand how to return extended object. For now I have something like this in controller
public function show(Site $id)
{
foreach ($id->features() as $feature) {
$id->features[] = $feature;
}
return $id;
}
And this is my model
class Site extends Model
{
protected $fillable = ['path', 'site_link'];
public $timestamps = false;
public function features() {
return $this->hasMany('App\SiteFeature');
}
}
For now it returns an empty array of features property.
If you are using implicit model binding then Lazy eager Load features relationship in controller action because model is already loaded
public function show(Site $site)
{
$site->load('features');
return $site;
}
If no implicit model binding then Eager load features using with at time of model loading
public function show($id)
{
$site = Site::with('features')->find($id);
return $site;
}
Check details for loading relationship https://laravel.com/docs/5.6/eloquent-relationships#constraining-eager-loads
So I have a model called data_storage and another model entity_states
I have to fetch the record from data_storage with entity_states where entity_state has data_storage_id and state_id.
How can I use eloquent to achieve this ?.
Or Ill have to use Query builder and use innerJoin?
Update1
My Actual Query
$this->values['new_leads'] = $data_storages->with('actions','states','sla')->where('wf_id',$wfid)->get();
My data_storage modal
class data_storages extends Model
{
//
protected $fillable = ['layout_id','member_id','company_id','team_id','data','status','wf_id'];
function actions()
{
return $this->hasMany('App\Models\ActionDataMaps', 'data_id', 'id' );
}
function states()
{
return $this->hasOne('App\Models\workflow_states','id','status');
}
function sla()
{
//Here I have to get those row from entity_states model where , data_storage_id and state_id
}
}
Thanks
Here's the more reasonable way to do it:
class DataStorage extends Model {
public states() {
return $this->belongsToMany(State::class,"entity_states");
}
}
class State extends Model {
public storages() {
return $this->belongsToMany(DataStorage::class,"entity_states");
}
}
Then you can eager-load related models via e.g.:
$storage = DataStorage::with("states")->first();
$storage->states->first()->column_in_related_state;
Or via the state:
$state = State::with("storages")->first();
$state->storages->first()->column_in_related_storage;
If there are additional columns in the pivot table entity_states then you can refer to them in the relationship as e.g.:
public states() {
return $this->belongsToMany(State::class)->withPivot("pivot_column");
}
In your model data_storage you can define a property / method entity_states to get them:
class data_storage extends Model
{
public function entity_states()
{
return $this->hasMany('App\entity_states','data_storage_id')->where('state_id ','=',$this->table());
}
}
Then you can access them in an instance by
$entityStatesOfDataStorage = $yourDataStorageInstance->entity_states;
See this link:
https://laravel.com/docs/5.3/eloquent-relationships
for Query Builder you may use this:
DB::table('data_storage')
->join('entity_states','data_storage.data_storage_id','=','entity_states.state_id')
->get();
For your reference Laravel Query Builder
I'm still struggeling with the laravel Models. At first I tried doing it all using the tables, but thats not smart, I'll miss out on lots of the laravel functions.
I have the following setup
ProjectTwitterStatus links the projects and the twitter statuses.
TwitterStatus has all the details of a twitter status and has a unique ID ('posted at' datetime of tweet is among the details)
TwitterRetweets has the ID of the TwitterStatus - the actual retweet - and the tweet ID of the retweeted status
TwitterReplies has the ID of the TwitterStatus - that is the actual reply - and/or the user ID if not a reply to a status but to a user.
What I want? To get for each date (DATE(datetime)) the count of the statuses, retweets and replies, using the laravel model relations.
These are the models.
class ProjectTwitterStatus extends Eloquent {
protected $table = 'project_twitter_statuses';
protected $softDelete = true;
public function twitterStatus() {
return $this->belongsTo('TwitterStatus');
}
public function project() {
return $this->belongsTo('Project');
}
}
class TwitterStatus extends Eloquent {
protected $table = 'twitter_statuses';
public function twitterRetweet() {
return $this->hasMany('TwitterRetweet');
}
public function twitterReply() {
return $this->hasMany('TwitterReply');
}
public function twitterUser() {
return $this->belongsTo('TwitterUser');
}
public function projectTwitterStatus() {
return $this->hasMany('ProjectTwitterStatus');
}
}
class TwitterRetweet extends Eloquent {
protected $table = 'twitter_retweets';
public function twitterStatus() {
return $this->belongsTo('TwitterStatus');
}
}
class TwitterReply extends Eloquent {
protected $table = 'twitter_replies';
public function twitterStatus() {
return $this->belongsTo('TwitterStatus');
}
}
I got the count of the twitterStatuses using this:
$twitterStatuses = TwitterStatus::has('projectTwitterStatus')
->groupBy(DB::raw('DATE(datetime)'))
->get(array(DB::raw('COUNT(id) AS tweets'),DB::raw('DATE(datetime) AS date')));
I tried for example this to get the retweet count added but that has no effect (a reference to the model apears in the object -> array().
$twitterStatuses = TwitterStatus::has('projectTwitterStatus')
->with(array('twitterRetweet' => function($query)
{
$query->count();
}))
->groupBy(DB::raw('DATE(datetime)'))
->take(10)
->get(array(DB::raw('COUNT(id) AS tweets'),DB::raw('DATE(datetime) AS date')));
Can anyone point me in the right direction?
Not 100% sure how your intended solution is to be used - Assuming you simply want a count of the number of retweets related to twitterStatus?
$count = $twitterStatus->twitterRetweet()->count();
where $twitterStatus is an already retrieved model - not a collection.
if $twitterStatus is a collection to iterate through you can also eager load the related model using either with() or load()
Then you can iterate through each model in the collection - depends on how you wanted to use the results
I am having issues getting the relationship array back when eager loading in laravel 4. for example:
controller:
foreach (Apps::with('extra')->get() as $app)
{
print_r($app->toArray());//returns array but my relationship array at the bottom says null
echo $app->extra; //this will show my relationship details
}
model:
class Apps extends Eloquent
{
protected $connection = 'mysql_2';
protected $table = 'apps';
public $timestamps = false;
protected $primaryKey = 'name';
public function host()
{
return $this->belongsTo('Hosts','name');
}
public function extra()
{
$this->primaryKey='app_ip';
return $this->hasone('Extra','ip');
}
//other functions below.......
}
class Extra extends Eloquent
{
protected $connection = 'mysql_3';
protected $table = 'extra';
public $timestamps = false;
protected $primaryKey = 'ip';
public function app(){
return $this->belongsTo('Apps', 'app_ip');
}
mysql:
My mysql tables were not created through laravel they were previously existent. the app_ip column in the Apps table relates to the ip column in the extra table. it is a 1 to 1 relationship and I have specified the primary key in the relationship function. I am getting relationships back so I know that it is working.
I am able to get relationship data back when I call the function directly, but it does not show the relationship data when I try and print the full array. The main goal is to be able to return both the relationship columns and the app columns in one response.
You need to do this:
$apps = Apps::all();
$apps->load('extra');
foreach ($apps as $app)
{
print_r($app->toArray()); // prints your relationship data as well
}
What you have should work and iterating through the collection or using ->load() to eager load shouldn't make a difference. Are you using the visible restriction on your models? If so you will need to include the relationships.
class Apps extends Eloquent {
protected $visible = array(
'id',
'name',
'created_at',
'extra', // Make the relationship 'visible'
);
public function extra()
{
return $this->hasMany('Extra');
}
}