We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

ManyToMany - Model::save() again

Hello,

I have a many to many relationship entities - entities_keywords (entities_id, keywords_id) - keywords. Searching works fine and as described. Now I want to save new entities. If the keywords are not stored in the database and I call entity->save() everything works great. But if just one of the keywords already exists, the whole query fails. So I want to override the save()-function in the model and after reading documentation and searching in the forum (some users got the same behaviour) I'm not quite clear how to do it properly.

My idea for creation a new entity: First I get all keyword as comma-seperated string; second I explode the string and search if the keyword exists, if not I save it; third I save entity's main data; fourth I save entity-keywords to the table (entities_keywords).

Questions are now:

  • How do I only save entity's main data? ... probably with parent::save($data)? And should I call it in Entities->save()?
  • If I get the keywords in $data['keywords'] where is the best place to check if they already exists? And how to prevent them from being stored by phalcon's built-in save-function?

It's very sad, that the manytomany-relation works fine for reading but makes saving much complicated :/

Thanks a lot.



98.9k

Could you please post some code that shows what you're trying to do?

edited Jul '14

Hi and thanks for your answer.

I've got three models: Ideas, Keywords, IdeasKeywords. Model Ideas does have some fields, especially the PK id. Model Keywords does have two fields, PK id and Unique title. Model IdeasKeywords has two fields, FK ideas_id and FK keywords_id; the PK is populated by Database with (ideas_id, keywords_id), so no entries can be doubled.

The idea and keywords are entered in a form by the user. The keywords are sent as a comma-seperated string.

Using the phalcon built-in functionality like shown here Phalcon Documentation a new Idea is saved if all Keywords are not yet stored in the database. The process does not succeed, if there is already one of them stored in the database.

Now I built the whole logic for creating (updating will come later) in the controller IdeaController. But I want the whole logic in a seperated file, best place therefore is probalby the Model Idea?!

I implemented the create logic this way: First it stores the new idea in the database table, now I've got the new ID in the object. Second it looks for every keyword if it is already in the database (Keywords::findFirst(array('conditions'=>'title=?1', 'bind' => ...))). If it is already stored it returns the object to an array, if it is not, it will be created and then put to the array. Third for the whole array, the new relations are stored in the table IdeasKeywords.

The documentation says "Note: Adding related entities by overloading the following methods is not possible: PhalconMvcModel::beforeSave(), PhalconMvcModel::beforeCreate(), PhalconMvcModel::beforeUpdate(). You need to overload PhalconMvcModel::save() for this to work from within a model."

But it is not said how to do that. As you see, I need to override Model::create() and Model::update(), because updating an idea could mean to delete some entries in IdeasKeywords.

Sorry, that I haven't post some of my code, but I don't know, if this is really helpful, because models are simple ones with no extra functionality for now. Many-to-many-Relationship works well, if I use $idea = findFirstById(1); $keywords = $idea->getKeywords();

Thanks a lot for your help.

edited Oct '14

Alright, got it. With try and error ... But docs should be more descriptive:

Override Model::create() means:

MyModel::create($data=null, $whitelist=null)
{
 ... do something
 if (parent::create($data, $whitelist) == FALSE)
     return FALSE;
... do something
return FALSE/TRUE;
}

Validators still works, and so on ...

Only thing, that does not work is the data persistent between the request for the form.