Phalcon Fatal Error on hasMany Relationship - orm

I have this ERD below:
Relations are as follow,
Entity to Host is One to One
Host to Portal is One to Many ( One Host to Many Portal )
class Entity extends Model
{
public function initialize()
{
$this->hasOne(
"entity_id",
"Host",
"entity_id"
);
}
}
class Host extends Model
{
public function initialize()
{
$this->belongsTo(
"entity_id",
"Host",
"entity_id"
);
$this->hasMany(
"host_id"
"Portal",
"host_id"
);
}
}
class Portal extends Model
{
public function initialize()
{
$this->belongsTo(
"portal_id",
"Host,
"portal_id"
);
}
}
When i try to retrieve the list of Portals base on the array of entity id provided, i got a fatal error.
Fatal error: Call to undefined method
Phalcon\Mvc\Model\Resultset\Simple::getHost()
This is my controller code to retrieve the portals
$hostObj = Host::find(['entity_id IN ({ids:array})',
'bind' => array('ids' => $entity_id)]);
if($hostObj)
{
$portals = $hostObj->Portal;
}
Basically the goal is to retrieve the list of Portals base on the array of entity_id provided. But i really wonder, whats wrong with my model relations that lead into the fatal error.

Find method returns Resultset, you need either to use findFirst or select row from Resultset(like array-like style $portals[0], or $portals->getFirst() or $portals->offsetGet('0')

Related

How to get the default $id from another table using laravel model relationship?

I am facing the problem whereby I don't know the syntax of letting the id of my property model equals to property_id value in property_doc table.
In PropertyDoc model
public function property()
{
return $this->belongsTo(Properties::class, 'property_id');
}
In Properties model
public function property_id()
{
return $this->hasMany(PropertyDoc::class, 'property_id');
}
In PropertyController
public function StoreInfoProperty(Request $request)
{
$propertyInfo = new PropertyDoc;
$propertyInfo->property_id = $property_id;
}
I am stuck at retrieving the default id value in properties database to be equal to the property_id in property_docs database. Thank you.
You should change the naming of the relationship, see my example below:
In Properties model
public function propertyDocs()
{
return $this->hasMany(PropertyDoc::class, 'property_id', 'id');
}
In PropertyDoc model
public function property()
{
return $this->belongsTo(Properties::class, 'property_id', 'id');
}
In controller
public function StoreInfoProperty(Request $request)
{
$propertyDoc = PropertyDoc::with(['property'])->where('...logic here');
$property_id = $propertyDoc->property->id;
}
hope can help you and happy coding !

Laravel hasManyThrough giving error when nesting

I essentially have 3 tables that I want to nest, 2 already work but I can't get hasManyThough to work.
My tables :
tablename : measurements
id
client_id (not important for now.)
tablename : measurement_data
id
measurement_id
measurement_field_id
data
tablename : measurement_fields
id
type_id (not important for now)
name
enabled
Heres my controller function :
public function index()
{
return JsonResource::collection(Measurement::with(['clients', 'measurement_data', 'measurement_fields'])->get());
}
My Model Measurement functions :
public function clients() {
return $this->belongsTo(Client::class, 'client_id');
}
public function measurement_field() {
return $this->hasMany(MeasurementData::class);
}
public function measurement_data() {
return $this->hasManyThrough(MeasurementField::class, MeasurementField::class, 'measurement_field_id', 'measurement_id');
}
My Model MeasurementData functions :
public function measurements() {
return $this->belongsTo(Measurements::class, 'measurement_id');
}
public function measurement_fields() {
return $this->hasOne(MeasurementType::class, 'type_id');
}
My Model MeasurementField functions :
public function measurements() {
return $this->belongsTo(MeasurementsData::class, 'measurement_field_id');
}
Whenever I fetch it I get this in console :
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'measurement_fields.measurement_field_id' in 'field list' (SQL: select `measurement_data`.*, `measurement_fields`.`measurement_field_id` as `laravel_through_key` from `measurement_data` inner join `measurement_fields` on `measurement_fields`.`id` = `measurement_data`.`measurement_id` where `measurement_fields`.`measurement_field_id` in (1, 2, 3))"
In Your Measurement Model Change
public function measurement_data() {
return $this->hasManyThrough(MeasurementField::class, MeasurementField::class, 'measurement_field_id', 'measurement_id');
}
TO
public function measurement_data() {
return $this->hasManyThrough(MeasurementField::class, MeasurementData::class, 'measurement_id', 'measurement_field_id');
}
Refer This
You have some mistakes about the relationships :)
In your Measurement model functions you have changed the the measurement_field and measurement_data.
Try this:
public function measurement_datas() {
return $this->hasMany(MeasurementData::class);
}
public function measurement_fields() {
return $this->hasManyThrough(MeasurementField::class, MeasurementField::class, 'measurement_field_id', 'measurement_id');
}
In your MeasurementField Model functions:
public function measurement_data() {
return $this->belongsTo(MeasurementsData::class, 'measurement_field_id');
}
In your MeasurementData Model functions:
public function measurement() {
return $this->belongsTo(Measurements::class, 'measurement_id');
}
public function measurement_field() {
return $this->hasOne(MeasurementType::class, 'type_id');
}
It is important to use the nameing convention. If it is a one-to-many relation, use plural on the 'many' side, and singular on the 'one' side. Also the name of the realtionship should indicate the name of the class that has been on the relationship, to avoid misunderstanding. Also try to give the correct key names which are presented in the db.
For more information you can find really clear and good documentation about this topic:
https://laravel.com/docs/8.x/eloquent-relationships
I fixed it, in Measurements I had :
public function measurement_data() {
return $this->hasManyThrough(MeasurementField::class, MeasurementField::class, 'measurement_field_id', 'measurement_id');
}
But, this fixed my problem :
public function measurement_fields() {
return $this->hasManyThrough(MeasurementField::class, MeasurementData::class, 'measurement_id', 'id');
}

Phalcon include relationships in json

I've been having a look at phalcon as an alternative to a laravel project that I'm running. It's mainly a REST api. I'm trying to figure out how to include relationships in a json response for models.
For example, if I had 2 models, set up like below:
class Clients extends \Phalcon\Mvc\Model
{
public function initialize() {
$this->hasMany('clientid','Contacts','clientid')
}
}
class Contacts extends \Phalcon\Mvc\Model {
public function initialize() {
$this->belongsTo('clientid','Clients','clientid')
}
}
And I did a:
$clients = Client::find();
return json_encode($clients->toArray());
How would I get it to automatically include the contacts?
I need to output to be something like this:
[{
clientid:'1111',
contacts:[
{
contactid:111
}
]
}];
Many thanks!
From the docs:
By accessing an attribute with the same name as the relationship will retrieve all its related record(s).
Based on the above, you should be able to access the contacts via the relationship defined like so:
$clients = Client::find();
$clientContacts = $clients->contacts;
// do something with the contacts
Edit:
Try to loop through your $contacts and then get the related record(s):
foreach ($clients as $client) {
// Do something with the contacts...
$contacts[$client->id] = $client->contacts;
}

Eager load Laravel Eloquent related model

I am trying to get eager loading working when fetching related models.
public function allCompanies() {
$companies = $this->companies()->active()->get();
$companies->load('Industry');
return $companies;
}
I have this function on the model Industry and I believe this should fetch the companies which are within the current industry, it should also fetch the related industry for the companies (this will be the current record)
This doesn't seem to work as when I iterate over the companies it re-fetches the Industry for each one.
Am I doing something wrong with the $companies->load('Industry'); line?
Thanks
Try:
public function allCompanies() {
$companies = $this->companies()->active()->with('industry')->get();
return $companies;
}
The with() and load() functions are referencing functions within the model not the model itself ie:
class Company extends Eloquent {
public function industry()
{
return $this->belongsTo('Industry');
}
}
class Industry extends Eloquent {
public function companies()
{
return $this->hasMany('Company');
}
}
Please reference http://laravel.com/docs/eloquent#eager-loading

Many to many relationship using Fluent Nhibernate Automapping

We are facing problem applying many-to-many relationship using fluent nhibernate automapping.
The simplified form of domain model are as follows:
public class Group
{
private readonly IList<Recipient> _recipients = new List<Recipient>();
public virtual IList<Recipient> Recipients
{
get { return _recipients; }
}
}
public class Recipient
{
private readonly IList<Group> _groups = new List<Group>();
public virtual IList<Group> Groups
{
get { return _ groups; }
}
}
As the code above describes that Group and Recipient are having many-to-many relationship.
We are using automapping feature of fluent nhibernate to map our domain model with database. So, we needed to use Convention for automapping.
Following is code we used for many to many convention:-
public class ManyToManyConvention : IHasManyToManyConvention
{
#region IConvention<IManyToManyCollectionInspector,IManyToManyCollectionInstance> Members
public void Apply(FluentNHibernate.Conventions.Instances.IManyToManyCollectionInstance instance)
{
if (instance.OtherSide == null)
{
instance.Table(
string.Format(
"{0}To{1}",
instance.EntityType.Name + "_Id",
instance.ChildType.Name + "_Id"));
}
else
{
instance.Inverse();
}
instance.Cascade.All();
}
#endregion
}
I found this solution here :
http://blog.vuscode.com/malovicn/archive/2009/11/04/fluent-nhibernate-samples-auto-mapping-part-12.aspx#Many%20to%20Many%20convention
But in above code while debugging both time for Recipients-> Groups and for Groups->Recipients instance.OtherSide is coming not null. The assumption was 1st time instance.OtherSide will be not null and second time it will be null as relationship is applied on one side so we will just apply inverse to that.
So it’s creating 2 mapping tables which are same.
It is load to database to have 2 tables of same schema. Even when I try to save our domain model to database using many to many relationship. It’s saving only 1 side i.e it saves Recipients in the Groups , But not saving Groups in Recipients.In database also it is having entry in only one mapping table not in both.
So , the question is Are we doing the right thing? If not then how to do it.
you could take inverse itself as a criteria
public void Apply(IManyToManyCollectionInstance instance)
{
Debug.Assert(instance.OtherSide != null);
// Hack: the cast is nessesary because the compiler tries to take the Method and not the property
if (((IManyToManyCollectionInspector)instance.OtherSide).Inverse)
{
instance.Table(
string.Format(
"{0}To{1}",
instance.EntityType.Name + "_Id",
instance.ChildType.Name + "_Id"));
}
else
{
instance.Inverse();
}
instance.Cascade.All();
}