This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.
First clone the following test plugin into your plugins directory:
https://github.com/meysammahfouzi/test-oc-relations
Then you should see a new menu added to your backend: "Stories".
There are two controllers for managing two models: Stories and Words.
There is a many-to-many relationship between stories and words.
First, go to the "Words" controller page, and create two words: "My" and "Story".
Now go to the "Stories" controller page and click on "Create" to create a new story. Fill in the title, e.g. "My story", and click "Create and close".
Back in the "Stories" controller page, click on "My story" row that you just created, to edit it.
In the edit page, click on the dropdown under "Add related words". You will see two words listed: "My" and "Story". Click On "My", you will see that it gets added to the list of the related words, in the list that has been rendered using "RelationController" at the bottom of the page. Now click on the other word, "Story", to add it as a related word as well.
Now in the dropdown under "Add related words", type a new word that does not exist in the list, like "Tale", and press enter. As you can see, it was created and added to the list of related words. When you select a word or type a new word in the dropdown, the following code in the custom form widget, adds the relationship to the current story, and refreshes the relation manager:
public function onAddWord()
{
$wordId = post($this->getFieldName());
if (is_numeric($wordId)) {
$this->model->words()->syncWithoutDetaching([$wordId]);
} else {
// if the word that user selected, was not in the list, wordId does not contain any ID,
// but it's the actual new word that needs to be added to the words table
$newWord = WordModel::create(
[
'title' => $wordId,
]
);
$this->model->words()->attach($newWord->id);
}
// refresh the relation manager list
return $this->controller->relationRefresh('words');
}
Now the problem is that this only works on the edit page of the story. If we want to create a new story, since there is no story ID yet, we get an error. To see the error, go to the "Stories" controller page. and click on the "Create" button. Now click on the dropdown under "Add related words", and select one of the words listed there, for example, "My". You get this error:
"SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'story_id' cannot be null (SQL: insert into
meysam_test_stories_words
(story_id
,word_id
) values (, 6))" on line 664 of projects/web/vendor/laravel/framework/src/Illuminate/Database/Connection.php
I know I have to use deferred-binding here, but don't know how! You may think that deferred-binding does not work here, but I can prove to you that it works here! How? As you can see, there is an "Add word" button, at the top of the list of the related words. Click on it. The list of the existing words is shown. Select one of them, like "My", and click "Add selected"; as you can see, it was added to the list! It indicates that deferred-binding is working here, by the RelationController. Now fill in some Title for the story and click "Create". Voila! It was created!
Now my question is, how can I use defered-binding in my onAddWord()
function to add a word to a Story that does not exist yet?
Last updated
1-1 of 1