Accessing a NULL related models in yii2 - yii2

In yii2 view I am accessing property of related model like below
$objPatientModel->physicianUser->diallingCode->phonecode
To explain it :
I have foreign key physician_user in patient table and in patient table I have dialling code (id from another table -- Diallingcodes) and in diallingcodes table I have attribute phonecode .
Now my problem is if in case value is physician_user is NULL then this throws the errors like 'try to get property of non object' which is because $objPatientModel->physicianUser returns NULL instead of empty object .I want to know is there any class or method that can be overridden in yii2 so that above error can be avoided without placing the checks ?

Use ArrayHelper.
\yii\helpers\ArrayHelper::getValue($objPatientModel, 'physicianUser.diallingCode.phonecode', null);
It returns NULL in case value in physician_user is NULL
ArrayHelper api

Related

Perl DBIx::Class encounterd Object Json

I'm new to Perl and DBIx::Class.
This is how I get my meaning_ids from the table translation where language = 5:
my $translations = $schema -> resultset('Translation')->search({ language => '5'});
After it I'm trying to push my data from the database into my array data:
while ( my $translation =$translations->next ) {
push #{ $data }, {
meaning_id => $translation-> meaning
};
}
$self->body(encode_json $data );
If I do it like this, I get the following error:
encountered object
'TranslationDB::Schema::Result::Language=HASH(0x9707158)', but neither
allow_blessed , convert_blessed nor allow_tags settings are enabled
(or TO_JSON/FREEZE method missing)
But if I do it like that:
while ( my $translation =$translations->next ) {
push #{ $data }, {
meaning_id => 0+ $translation-> meaning
};
}
$self->body(encode_json $data );
I don't get the error anymore, but the meaning is not the number out of the database. It's way too big (something like 17789000, but only numbers till 7000 are valid).
Is there an easy way to tell Perl that meaning_id is an INT and not a string?
It's a bit hard without knowing your schema classes, but #choroba is right. The error message says $translation->meaning is an instance of TranslationDB::Schema::Result::Language. That's explained in DBIx::Class::Manual::ResultClass on CPAN.
I believe there is a relationship to a table called meaning, and when you call $translation->meaning what you get is a new result class. Instead you need to call $translation->meaning_id. Actually that would only happen in a join, but your code doesn't look like it does that.
It seems $translation->meaning returns an object. Using 0+ just returns its address (that's why the numbers are so high).
It looks like there's a relationship between your translation and meaning tables. Probably, the translation table contains a foreign key to the meaning table. If you look in the Result class for your translation class then you will see that relationship defined - it will be called "meaning".
As you have that relationship, then DBIC has added a meaning method to your class which retrieves the meaning object that is associated with your translation.
But it appears that the foreign key column in your translation table is also called "meaning", so you expect calling the "meaning" method gives you the value of the foreign key rather than the associated object. Unfortunately it doesn't work like that. The relationship method overrides the column method.
This is a result of bad naming practices. I recommend that you call the primary key for every table id and the foreign key that links to another table <table_name>_id - so the column in your translation table would be called meaning_id. That way you can distinguish between the value of the key ($translation->meaning_id) and the associated meaning object ($translation->meaning).
A work-around you can use if you can't rename columns, is to use the get_column method - $translation->get_column('meaning').

Update empty string to NULL in a html form

I'm building a site in Laravel.
I have foreign key constraints set up among InnoDB tables.
My problem is that if i don't select a value in a, say, select box, the framework tries to insert or update a record in a table with '' (empty string). Which causes a MySQL error as it cannot find the equivalent foreign key value in the subtables.
Is there some elegant way to force the insertion of NULL in the foreign key fields other than checking out every single field? Or to force MySQL to accept '' as a "null" foreign key reference?
In other words: I have a, say, SELECT field with first OPTION blank. I leave the blank OPTION chosen. When I submit, an empty string '' is passed. In MySQL apparently I can do UPDATE table SET foreignKey=NULL but not UPDATE table SET foreignKey=''. It does not "convert" to NULL. I could check the fields one by one but and convert '' to NULL for every foreign key, maybe specifying all of them in an array, I was wondering if there's a more streamlined way to do this.
Maybe have to change my ON UPDATE action (which is not set) in my DB schema?
Edit: the columns DO accept the NULL value, the problem is in how the framework or MySQL handle the "empty value" coming from the HTML. I'm not suggesting MySQL "does it wrong", it is also logical, the problem is that you can't set a "NULL" value in HTML, and I would like to know if there's an elegant way to manage this problem in MySQL or Laravel.
In other words, do I have to specify manually the foreign keys and construct my query accordingly or is there another robust and elegant way?
My code so far for the model MyModel:
$obj = new MyModel;
$obj->fill(Input::all())); // can be all() or a subset of the request fields
$obj->save();
At least since v4 of Laravel (and Eloquent models), you can use mutators (aka setters) to check if a value is empty and transform it to null, and that logic is nicely put in the model :
class Anything extends \Eloquent {
// ...
public function setFooBarAttribute($value) {
$this->attributes['foo_bar'] = empty($value)?null:$value;
}
}
You can check out the doc on mutators.
I've been oriented by this github issue (not exactly related but still).
Instead of using
$obj = new MyModel;
$obj->fill(Input::all())); // can be all() or a subset of the request fields
$obj->save();
Use
$obj = new MyModel;
$obj->fieldName1 = Input::get('formField1');
$obj->fieldName2 = Input::has('formField2') && Input::get('formField2') == 'someValue' ? Input::get('formField2') : null;
// ...
$obj->save();
And make sure your database field accepts null values. Also, you can set a default value as null from the database/phpmyadmin.
You must remove the "not null" attribute from the field that maps your foreign key.
In the model add below function.
public function setFooBarAttribute($value)
{
$this->attributes['foo_bar'] = $value?:null;
}

Grails property cannot be null error

My Grails app worked fine. If I remember corectly all I did was to change a contraint on one of my domain classes from blank: true, nullable:true to blank:false, nullable: false. And now when I try to create a new instance of that class I get following error messages:
Property [contract] of class [class com.app.Request] cannot be null
Property [description] of class [class com.app.Request] cannot be null
Property [productline] of class [class com.app.Request] cannot be null
Property [requestType] of class [class com.app.Request] cannot be null
Property [subject] of class [class com.app.Request] cannot be null
And I've provided values for all of these properties.
I'm guessing there is some conflict between gorm and database. Can someone explain to me whats going on and how to fix it.
I had similar problem, had updated constraints to non-null, but my stored data had nulls for non-null fields. At some point Grails tries to load existing data, but fails on validation step.
Try to update your database with some default values (I mean by using plain SQL UPDATE SET x = 'temp' WHERE x IS NULL), make grails clean and restart your app. Should help.

EF 4.1 Table-per-Hierarchy

I'm trying to implement a simple TPH example from http://msdn.microsoft.com/en-us/library/dd793152.aspx. I have two tables:
PERSON
[PersonID] [int] IDENTITY(1,1) NOT NULL,
[PersonTypeID] [int] NOT NULL,
[Name] [varchar](50) NOT NULL,
[HourlyRate] [int] NULL
PersonType
[PersonTypeID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL
In EF designer, I follow the tutorial and create a new Entity called Employee and specify Person as the base type. Then move the HourlyRate property to Employee. In the Mapping Details window, I map the entity to the Person table and it properly maps HourlyRate property to the correct DB field. Then I set Person to abstract.
If I build it now without specifying a condition and a discriminator in the Employee entity, it builds fine. If I follow the tutorial and specify HourlyRate as the condition and use "Is" "Not Null" as the discriminator, it builds fine.
But I want to use PersonTypeID as the discriminator and an Employee should have a PersonTypeID of 1. So I select PersonTypeID as the the condition field, "=" as the operator, and 1 as the value. When I build, VS tells me the it's successful but also has something in the Error window.
Error 3032: Problem in mapping fragments starting at line
798:Condition member 'Person.PersonTypeID' with a condition other than
'IsNull=False' is mapped. Either remove the condition on
Person.PersonTypeID or remove it from the mapping.
I read in another article that I need to delete the PersonType navigation property in the Person Entity. So I tried that but still got the same error.
I thought I was able to get this to work before on another project but I'm not sure what changed for this one. The only thing different that I can think of is that I recently updated to EF 4.1.
This is what I have set up in the designer
Any suggestions are greatly appreciated!
I figured it out. Adding the PersonType entity to the designer threw everything off. The key was to delete the PersonType navigation property as well as the PersonTypeID property. But since I included the PersonType entity, deleting PersonTypeID broke the foreign key constraint.
By not including PersonType entity, I can delete PersonTypeID and everything compiles successfully.

linq to sql string property from non-null column with default

I have a LINQ to SQL class "VoucherRecord" based on a simple table. One property "Note" is a string that represents an nvarchar(255) column, which is non-nullable and has a default value of empty string ('').
If I instantiate a VoucherRecord the initial value of the Note property is null. If I add it using a DataContext's InsertOnSubmit method, I get a SQL error message:
Cannot insert the value NULL into column 'Note', table 'foo.bar.tblVoucher'; column does not allow nulls. INSERT fails.
Why isn't the database default kicking in? What sort of query could bypass the default anyway? How do I view the generated sql for this action?
Thanks for your help!
If you omit the column, the value becomes the database default, but anything you insert is used instead of the default, example:
INSERT INTO MyTable (ID, VoucherRecord) Values(34, NULL) -- Null is used
INSERT INTO MyTable (ID) Values(34) -- Default is used
Picture for example you have a column that defaults to anything but NULL, but you specifically want NULL...for that to ever work, whatever value you specify MUST override the default, even in the case of NULL.
You need to set Auto-Sync to OnInsert, Auto Generated Value to true and Nullable to false for your column to work. See here for a full run-down with explanation on the Linq side.
For viewing the generated SQL, I have to recommend LinqPad