cakebake not working with prefix in cakephp3 - caph-framework

I am using cakephp 3.4.9. When I am using a table with prefix n field its working properly after baking but if I use prefix in table fields its not working.
Like when I am using post with following fields like
id,
post,
date
it's working fine but if I use following fields its not working
p_id,
p_post,
p_date
it is adding extra codes in model
$this->belongsTo('Ps', [
'foreignKey' => 'p_id',
'joinType' => 'INNER'
]);
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['p_id'], 'Ps'));
return $rules;
}
why ps is adding here? If I use articales table like same its become As.
Please help.

I would like to suggest you, read this article.
CakePHP naming convention documentation
In cakePHP framework everything you have to keep in mind while creating the table is the CakePHP naming conventions. In your case, This is happening because cakePHP expects the primary column of any table will be only 'id', and the foreign key for the table will be the Related table name with an underscore id
(ex: If product table BelogsTO categories you have to make a column in your product table as category_id)
In your case cakePHP considering p_id as a foreign key for the table P. And by default cakePHP has a validation for the forein key that the existsIn which means that while saving that p_id, it will check for the existance of id in P table.
In one sentense this is because of the naming convention issue. You can change only p_id to id and keeping other things same will work for you.
HAPPY CODING :)

Related

I get duplicate entries with the attach method in Laravel 5. Not sure what the problem is

So I'm trying to attach id's with some meta data to a pivot table in Laravel 5.
For some reason, I get the two inserts where there should be one, and the wrong ID's being inserted the second time round.
I'm not sure if there is something I might be missing here.
This is the code:
$match_values = array(
'dataId' => $result->id,
'dataMetaId' => $the_meta->id
);
$result->campaignDataMeta()->attach($match_values, [
'meta_value' => $value
]);
The database structure consists of a main campaignData table for email campaigns, a campaignDataMeta table (id, timestamps, name) for email meta data names, and a lookup table campaignDataMatches (id, campaignDataId, campaignDataMetaId, meta_value).
In campaignDataMatches I get the campaignDataId value sometimes being inserted into the campaignDataMeta column.
I've solved the problem.
Apparently had to add the relevant ID (in this case the dataMetaId) within the attach parameter.
Like this:
$result->dataMeta()->attach([$data_meta_id => [
'meta_value' => $value
]]);
Check the database columns primary maybe the dataId and metaId are both primary.

Laravel Validation Rule

I have category table
Its has del_status
when delete category delstatus will change 1
now question is
when update category ,
I want to validate except del_status 0
because category is unique
eg below is pseudo code :)
Rule::except(function ($query){
return $query->where('del_status','1');
})
You should use The softDelete traits in your model. it will spare you a lot of trouble and will work as you want it to.
https://laravel.com/docs/5.7/eloquent#soft-deleting
it will use a field in the DB table name deleted_at

Retrieve related table and select fields from primary table using Laravel Artisan

In the following code, The Users table has a related table phoneNumbers. When I retrieve a list of all users like this,
return Person::with('phoneNumbers')->get();
everything works fine. However, when I attempt to specify a list of columns to return from the Person table, the phone_number returns empty.
return Person::with('phoneNumbers')
->get(['fname','lname', 'email']);
If I add the number field or phone_number.number to the get array, then I get an error as an undefined column. What is the laravel way of handling this.
Try this:
return Person::select(['your_foreign_key', 'fname','lname', 'email'])
->with('phoneNumbers')get();

Laravel validation: unique with multiple columns and soft_delete

I am trying to do a Laravel validation rules as follow:
"permalink" => "required|unique:posts,permalink,hotel_id,deleted_at,NULL|alpha_dash|max:255",
The explanation to the rules is:
I have a table "Posts" in my system with the following fields (among others): hotel_id, permalink, deleted_at. If MySQL would allow make an unique index with null values, the sql would be:
ALTER TABLE `posts`
ADD UNIQUE `unique_index`(`hotel_id`, `permalink`, `deleted_at`);
So: I just add a new row IF: the combination of hotel_id, permalink and deleted_atfield (witch must be NULL) are unique.
If there is already a row where the permalink and hotel_id field are the same and 'deleted_at' field is NULL, the validation would return FALSE and the row wouldnt be inserted in the database.
Well. I don't know why, but the query Laravel is building looks like:
SELECT count(*) AS AGGREGATE FROM `posts`
WHERE `hotel_id` = the-permalink-value AND `NULL` <> deleted_at)
What the heck...
The query I was hoping Laravel build to validation is:
SELECT count(*) AS AGGREGATE FROM `posts`
WHERE `permalink` = 'the-permalink-value' AND `hotel_id` = ? AND `deleted_at` IS NULL
Could someone explain me how this effectively works? Because everywhere I look it looks like this:
$rules = array(
'field_to_validate' =>
'unique:table_name,field,anotherField,aFieldDifferentThanNull,NULL',
);
Does anyone could help me?
Thank you
all.
Finally, I got a proper understanding of the validation (at least, I think so), and I have a solution that, if it is not beautiful, it can helps someone.
My problem, as I said before, was validate if a certain column (permalink) is unique ONLY IF other columns values had some specific values. The problem is the way Laravel validation string rules works. Lets get to it:
First I wrote this:
"permalink" => "required|unique:posts,permalink,hotel_id,deleted_at,NULL|alpha_dash|max:255",
And it was generating bad queries. Now look at this:
'column_to_validate' => 'unique:table_name,column_to_validate,id_to_ignore,other_column,value,other_column_2,value_2,other_column_N,value_N',
So. The unique string has 3 parameters at first:
1) The table name of the validation
2) The name of the column to validate the unique value
3) The ID of the column you want to avoid (in case you are editing a row, not creating a new one).
After this point, all you have to do is put the other columns in sequence like "key,value" to use in your unique rule.
Oh, easy, an? Not so quickly, paw. If you're using a STATIC array, how the heck you will get your "currently" ID to avoid? Because $rules array in Laravel Model is a static array. So, I had to came up with this:
public static function getPermalinkValidationStr() {
$all = Input::all();
# If you are just building the frozenNode page, just a simple validation string to the permalink field:
if(!array_key_exists('hotel', $all)) {
return 'required|alpha_dash|max:255';
}
/* Now the game got real: are you saving a new record or editing a field?
If it is new, use 'NULL', otherwise, use the current id to edit a row.
*/
$hasId = isset($all['id']) ? $all['id'] : 'NULL';
# Also, check if the new record with the same permalink belongs to the same hotel and the 'deleted_at' field is NULL:
$result = 'required|alpha_dash|max:255|unique:posts,permalink,' . $hasId . ',id,hotel_id,' . $all['hotel'] . ',deleted_at,NULL';
return $result;
}
And, in the FrozenNode rules configuration:
'rules' => array(
'hotel_id' => 'required',
'permalink' => Post::getPermalinkValidationStr()
),
Well. I dont know if there is a easiest way of doing this (or a much better approach). If you know something wrong on this solution, please, make a comment, I will be glad to hear a better solution. I already tried Ardent and Observer but I had some problems with FrozenNode Administrator.
Thank you.

How to disambiguate column names in yii MANY_MANY relation

I have a nice case of folder and item in the folder. All mysql is abbreviated for clarity.
CREATE TABLE folder
folder_id INT,
name VARCHAR(32),
sort_weight INT
CREATE TABLE item
item_id INT,
name VARCHAR(32)
and of course the linking table
CREATE TABLE item_folder
folder_id INT,
item_id INT,
sort_weight INT
As you might have guessed one item can be in more than one folder (sort of like hard links in linux file system) and notice that folder has sort_weight too becuase it can be sorted inside another folder. Now I am using Yii and I have a nice relation in Item model like this:
public function relations()
{
return array(
'folderitems' => array(self::MANY_MANY, 'Folder', 'item_folder(item_id, folder_id)'),
);
}
The problem is that when I try to make some nice AR request and I try to sort it I have a problem. My AR request:
$items = Item::model()->with(array(
'folderitems' => array(
'condition' => "folderitems.folder_id = $someid"
),
))->findAll(array('order'=> "folderitems.sort_weight"));
Now the problem is, that with syntax like this, instead of sorting by item_folder.sort_weight it sorts by folder.sort_weight.
If I change the name of the field to say item_folder.sort_weight2 and try:
[...] ))->findAll(array('order'=> 'sort_weight2'));
it works.
However if I keep both names the same and try
[...] ))->findAll(array('order'=> 'item_folder.sort_weight'));
it says unknown column.
So the question is - how to disambiguate it correctly.
try
[...] ))->findAll(array('order'=> 't.sort_weight'));
http://www.yiiframework.com/doc/guide/1.1/en/database.arr#disambiguating-column-names
"When a column name appears in two or more tables being joined together, it needs to be disambiguated. This is done by prefixing the column name with its table's alias name.
In relational AR query, the alias name for the primary table is fixed as t, while the alias name for a relational table is the same as the corresponding relation name by default."

Resources