Concat String to a number returns zero - php

I'm having a table whith 'id' as pk of type int.
When I'm doing the folowing mysql query in php activerecord
Location_cat::find_by_sql("select concat('#',id) as 'id', text FROM location_cat");
it returns 'id' as 0, instead of '#142'for example.
Does anyone knows this behavior?

You are trying to overwrite the 'id' field, but this will give you issues. An activerecord object knows it's own primary key (i'd assume the id-field), and uses it for all sorts of stuff. If you try to select something else into that field, this will not work.
For instance, you get the object with id 1. This is renamed to #1 by you. now AR thinks it is an object with a primary key that is #1. Which is not true
Bottomline is, you should not put something else in the id field if you want to work with an actual activerecord object.
What you might want to do is just get the data, but on returning the $object->id field, you can add the #. For instance, make a magic getter for id (I believe AR allows you to name this getId(), but otherwise, fix it in __get().

Lets Cast the id into a string before concatenating
SELECT CONCAT('#', CAST(id AS CHAR(15))) AS nid
FROM location_cat

Related

Laravel eloquent model model attribute casting (Which attribute types should I cast?)

I am not sure I fully understand Laravel Eloquent attribute casting. According to documentation, (https://laravel.com/docs/8.x/eloquent-mutators#attribute-casting), these are the supported types:
integer, real, float, double, decimal:, string, boolean, object, array, collection, date, datetime, timestamp, encrypted, encrypted:object, encrypted:array, and encrypted:collection
So far, I've only used date casting on my models (when the fields were stored as timestamps in the db), like this:
protected $dates = [
'modified_at', 'published_at'
];
I also understand the need for attribute casting to boolean when the values are stored as integers (0 or sth else).
But what about other attribute types (integers, for example), should I always do attribute casting? Or just when the field in the database is of a different type? What are the use cases or what is the best practice with other attributes?
(I can't, for example, imagine creating a string field in migrations, then saving some number inside it as string and then casting it back into an integer on the model?)
By default, attributes will be casted to the type of column defined in the table. So, if your column is an integer, then it will be casted as int.
But, what happens if you want to modify this behavior for specific fields? That's when attribute casting enters the scene.
For example, imagine we have in a table called projects a column named config of type json in which we can store additional configuration elements for each project.
In my case, it'd be useful to be able to handle this data as an array. So, instead of receiving a string or object, we can just deal with a simple array. To do this, we just:
class Project extends Model
{
// ...
protected $casts = [
'config' => 'array',
];
// ...
}
This way, whenever we use Eloquent to fetch projects from the database, each record will have that property as an array. And also, it will be converted back to json when trying to store/update records.
Related to the case you specified (saving element as a string but then retrieve it as an integer) is totally possible of course. You'll need to set both the accessor and the mutator for that field. For an attribute named number:
/**
* This will be called when fetching the element.
*/
public function getNumberAttribute($value)
{
return (int)$value;
}
/**
* This will be called when storing/updating the element.
*/
public function setFirstNameAttribute($value)
{
$this->attributes['number'] = (string)$value;
}
Now, a reason to ever need to make this? Well, you could be dealing with a database not properly well designed, or with a production database that is being used by multiple systems and changes in the db are hard to accomplish. In those cases you could make use of this kind of value manipulation to work as you want in your app.

Code igniter query with autoincrement id return true even if id is wrong

So recently I'm making a simple CRUD app with Codeigniter.
My table has id field that is an auto increment field.
My model has a function called getById.
public function getById($id){
return $this->db->get_where($this->_table,["id" => $id])->row();
}
In my table, I have 1 field with ID of 1.
If I try to query with wrong ID, it return empty.
However, when I try to input something like 1 followed with string like
1test
it did return the field with id 1 in my database. I don't know if this is how it should be or is it a bug.
Surely Codeigniter is casting your string to integer.
PHP intval() manual says:
Strings will most likely return 0 although this depends on the leftmost characters of the string. The common rules of integer casting apply.
So, if you need to throw an error on invalid entries, you must validate them first, maybe using is_int() to allow only integer type or is_numeric() to allow strings containing only numbers.

Filtering a query in parse that the key is a pointer

Im a bit new to the php side of parse, mainly objective-c and swift but I need to write some code that I can query a column (not the objectID one) to return the results..
The column I'm trying to query is a pointer to another class.
Here is the very basic code I have which returns all the rows in the class and the pointers data with the include key, but I need to filter or get only the row/s that I'm looking for.
$query = new ParseQuery("ClassB");
$query->includeKey("ClassA");
$results = $query->find();
In the php sdk I see an option to use equalTo which has a key and a value to it so I tried the following code.
so I choose the column that was the pointer , and its objectid to hopefully only return those row/s that has that object id.
$query = new ParseQuery("ClassB");
$query->includeKey("ClassA");
$query->equalTo("ColumnNameX", "yjdyaGRWP7");
$results = $query->find();
Nothing was returned and a php error was spit out
'pointer field ColumnNameX needs a pointer value' in /var/www/parse/src/Parse/ParseClient.php:326
So im not 100% sure why I cant filter by a ColumnNameX using its objectID which is a pointer to ClassA..
Did I miss something in the PHP docs..
I mean ideally in mysql to just get that row I want would be
SELECT * FROM ClassB WHERE ColunNameX = yjdyaGRWP7
That would return me the row of data, I can use a Join of course to get some info from ClassA as well.
Any thoughts on what im missing or do I need to first query the Class A to get a pointer, then in the equalTo do something like ("ColumnNamX" , $pointerfromClassA) ?
any one have anyone point out what im missing or have a code example.. I have seen some that use the objectID but I dont have access to that.
Ok I figured out one way to do this, not sure if this is the right way but it returns now what I want..
$query->equalTo("ColunNameX", array("__type" => "Pointer", "className" => "ColunNameX", "objectId" => "yjdyaGRWP7"));

Yii2 findOne returns me an array, but not an Object(ActiveRecord)

I'm trying to use afterFind method of an Model
public function afterFind() {
$group = GroupMember::findOne(1);;
Yii::info($group->id);
parent::afterFind();
}
And the error is
Trying to get property of non-object
I found that findOne return an array with column values.
My question is what I'm doing wrong, or just afterFind if making this?
Thanks.
Look at the docs, findOne() can not return array.
Most likely record with id = 1 dosn't exist and you get null. afterFind() has nothing to do with it.
#Awesome AP - this is not urgent syntax error(with the ";;")
#arogachev - in the documentation there is said that
Returns a single active record model instance by a primary key or an
array of column values
and its really returns me an array, but I don't know why.
Luckily I fix it by $group = GroupMember::find(1)->one();.
But tanks you all for helping me.
This question is quite old but arogachev is right.
findOne either return an ActiveRecord or Null, you got null
About the documentation, you read the method description and not what it return, just go to end and you find:
return static|null
ActiveRecord instance matching the condition, or null if nothing matches.
The description:
Returns a single active record model instance by a primary key or an array of column values.
The phrase is not very clear but it means that you can pass as query filter an id or an array of columns name => value to use as query filter. Since version 2.0.37 Expression can be passed

Phalcon PHP: test Uniqueness on a natural key?

I've got some code like this:
$this->validate(new \Phalcon\Mvc\Model\Validator\Uniqueness(['field' => $field]));
if (true == $this->validationHasFailed()) {
throw new SpecialInternalUniqueException();
}
This works for all columns except for natural Primary Keys. That is, Primary Keys that are not surrogate keys (auto-incrementing integers). For example, in the job_titles table, the natural key column is "job_title" - which, in our case, refers to the name of the job title. This name should be unique, and I want to be able to check for that in the code prior to saving. However, Phalcon happily ignores it, somehow.
I'm actually setting up a unit test for this right now and doing something similar to the following:
$job_title = new JobTitles();
$job_title->job_title = 'Unique Test';
$job_title->description = 'Desc A';
$job_title->save();
$job_title2 = new JobTitles();
$job_title2->job_title = 'Unique Test';
$job_title->description = 'Desc B';
$job_title->save();
The exception never gets thrown. What ends up in the database is a single column for the first Unique test with Desc A, and no record for the second one. But I don't get a thrown exception.
Any thoughts?
EDIT:
Also, I've tried with the ->create() function in place of the save() function.
First you should be aware that in the default behavior those validations are created from the actual database schema right after the model class is initialized; you're not supposed to add them manually in that case.
In other words, the default meta-data strategy for models is the Database Introspection Strategy
So a exception will only be raised if the job_title field is already indexed for uniqueness checking in the database scheme. If you aren't able to actually create this PK in the database, you may change the default meta-data strategy for your models and them set the metadata manually (sigh).

Categories