This question already has an answer here:
X is not associated to Y
(1 answer)
Closed 2 years ago.
I have read all the documentation on Stack Overflow and Sequelize website.
My database have the correct foreign keys. I associated IMAGES model to CREATION:
Images.associate = (models) => {
Images.belongsTo(models.Creations, {
foreignKey: 'idImagesCreation',
sourceKey: 'id',
onDelete: 'CASCADE',
});
};
In my controller I call like this
list(req, res) {
return Creations
.findAll({
raw: true,
include: [{
model: Images
}]
}).then(creations =>{ etc...
I have tried with "as" including {as: 'Images'} in my model and in my controller but still have the same error :
SequelizeEagerLoadingError: Images is not associated to Creations!
I have doubts on '(models)' parameter, where does associate find the models ?
I import them in the index file of the models folder. Is this sufficient?
Or does the error come from another source?
That's because as Sequelize says the models are not associated that way. You have the association from Images to Creations, but not from Creations to Images, so what you need to do is make that association like this:
Creations.associate = (models) => {
Creations.hasOne(models.Images, { as: 'ImagesCreation' });//hasMany depending on your relationship
};
This creates a FK on Images with the name ImagesCreationId, now you do the second association.
Images.associate = (models) => {
Images.belongsTo(models.Creations);
};
Now Sequelize knows the association the way you want.
I would recommed to do the migration so you have now the right association.
Related
I am trying to create a big request for most of the page data. A certain model has polymorphic relations to a few other models, which in turn have normal relations to other models. What I am trying to achieve is fetch those "sub-relations" along with the polymorphic objects. Something like:
filter = {
include: [{
canvas: {
points: {
device: [
{
relation: 'chart',
scope: {
where: {
type: 'line',
},
},
},
'model',
],
},
}
}],
}
As displayed under the device (which is the polymorphic relation attribute), I also include two relations, chart and model. Those relations only exist in one type of device chartDevice, and if the query fetches such rows, it works. However, if the query fetches other types, e.g. networkDevice, which does not include such relations, it crashes.
Also, if I try to include a relation specific to networkDevice, it doesn't work.
I guess Loopback might not support that in polymorphic relations, but I am curious if there is any workaround that I might have not thought of.
So I'm working in an AngularJs app that is connected to a Kinvey backend. www.kinvey.com
In Kinvey we can fetch an entity and it's relations like this:
var promise = $kinvey.DataStore.get('events', 'event-id', {
relations : { location: 'locations' }
});
http://devcenter.kinvey.com/angular/guides/datastore#JoiningOperators
Relational Data / Fetching
The above is actually getting an event entity from the events collection and it's also fetching the data of the locations associated to it (which are in a different collection), so far so good we are able to retrieve an entity and it's associated entities ...
Now how could I retrieve the associations of those locations ?
In other words how can I retrieve nested associations ?
Thanks.
Like this:
$kinvey.DataStore.find('collection1', null, {
relations: {
name: "collection2",
"name.name": "collection3"
}
});
https://support.kinvey.com/discussion/201272198/nested-relations
I am trying to create a backbone client side application. I am receiving a list of json objects from the server on startup that will be a list of the possible tables exposed from the server, with their structure. E.g. Customers, Orders, Invoices, Employees
I want to create the models, collections and views dynamically based on the data I receive from the server.
Only when I receive the json on load will I know what the models should be and what the relationships between the models should be.
E.g. Customers structure might be Id, CustomerName, Address, Contact Numbers.
Order Structure might be Id, CustomerId, OrderDate, Amount
etc
By building Models, collections, views, controllers dynamically, I could in theory on startup point at another server who might give me a totally different set of tables e.g. : Movies, Actors etc.. with their structures.
Also, if additional fields are added I don't have to change the client side code again. E.g. Customer table might include a new field called ContactPerson
Please assist me as all the examples I saw on backbone is all based on statically defining the models on the client side up front. So create a model and collections and views for Customers, Orders, Invoices, Employees etc. etc.
Best wishes,
Andy
As already mentioned in the comments, Backbone models are dynamic by nature. So this is perfectly valid for example:
// A example dataset, this could be returned as JSON from the server
var jsonDataA = [
{
name: "Foo",
title: "Bar"
},
{
name: "a",
title: "b"
}
],
// A different example dataset
jsonDataB = [
{
make: "X",
model: "Y"
},
{
make: "Z",
model: "ZZ"
}
],
MyModel = Backbone.Model.extend({
/* Empty Model definition */
}),
MyCollection = Backbone.Collection.extend({
model: MyModel
}),
collection = new MyCollection();
collection.reset(jsonDataA);
console.log(collection.models);
collection.reset(jsonDataB);
console.log(collections.models);
Here I have reused the same Collection and Model definition to store completely different datasets.
One part is the raw data, the other part is its relations. You need to transport the metadata also, which contains the types and their relations. Model attributes will be populated automatically.
From your metadata a simple object can be constructed, where the keys describe one entity, for example:
var entites = {};
entities["Customer"] = Backbone.Model.extend({
/* Model definition based on metadata */
});
var parametersFromServer = {name: "John Doe"};
var customer = new entities["Customer"](parametersFromServer);
For building relations I would recommend using BackboneRelational plugin.
I'm writing an application that uses Zend Framework 2 and Doctrine (both the latest stable version).
There is much documenation (mainly tutorials and blog posts) that deal with saving doctrine entities to the database in combination with Zend Form. Unfortunately they only deal with simple entities that do not have one-to-many or many-to-many relationships.
This is one of those examples that i have adopted into my own code.
http://www.jasongrimes.org/2012/01/using-doctrine-2-in-zend-framework-2/
I understand that in the Album Entity of this example, the artist is a string to keep the (already lengthy) tutorial as simple as possible. But in a real world situation this would of course be a one-to-many releationship with an Artist Entity (or even a many-to-many). In the view, a select-box could be displayed where the artist can be selected, listing all the artist-entities that could be found in the database, so the right one can be selected.
Following the example with the album, this is how i've set up an 'edit' Action in my controller:
public function editAction()
{
// determine the id of the album we're editing
$id = $this->params()->fromRoute("id", false);
$request = $this->getRequest();
// load and set up form
$form = new AlbumForm();
$form->prepareElements();
$form->get("submit")->setAttribute("label", "Edit");
// retrieve album from the service layer
$album = $this->getSl()->get("Application\Service\AlbumService")->findOneByAlbumId($id);
$form->setBindOnValidate(false);
$form->bind($album);
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
// bind formvalues to entity and save it
$form->bindValues();
$this->getEm()->flush();
// redirect to album
return $this->redirect()->toRoute("index/album/view", array("id"=>$id));
}
}
$data = array(
"album" => $album,
"form" => $form
);
return new ViewModel($data);
}
How would this example need to be altered if the artist wasn't a string, but an Artist Entity?
And suppose the album also has multiple Track Entities, how would those be processed?
The example would not need to be changed at all, the changes will happen with your entity and your form.
This is a good reference: Doctrine Orm Mapping
So to save yourself a lot of extra work, your OnToMany relationship would use: cascade = persist:
/**
* #ORM\OneToMany(targetEntity="Artist" , mappedBy="album" , cascade={"persist"})
*/
private $artist;
When it comes to persisting the form object, the entity knows it must save the associated entity as well. If you did not include this, then you would have to do it manually using a collection.
To make like easier with your form, you can use Doctrines Object Select like this:
$this->add(
[
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'artist',
'options' => [
'object_manager' => $this->objectManager,
'target_class' => 'Artist\Entity\Artist',
'property' => 'name', //the name field in Artist, can be any field
'label' => 'Artist',
'instructions' => 'Artists connected to this album'
],
'attributes' => [
'class' => '', //Add any classes you want in your form here
'multiple' => true, //You can select more than one artist
'required' => 'required',
]
]
);
So now your form takes care of the collection for you, the controller as per your example does not need to change since the entity will take care of the persisting...
Hope this gets you on track.
I currently have two Backbone models: user and project. I would like to have a Backbone view containing a form that enables the creation of a new project, and the association of currently existing users (entries from the database users table) with this project. When a user completes this form and clicks the save button, the new project should be saved into the database (in the projects table) and the relationship between the saved project and the related users should be saved into a relationship table (projects_users table, containing the corresponding project id and the user id for each relationship). Currently, I can save the project information, but could not get any data into the projects_users table using Backbone-relational.
What do you think the best approach to achieve the above functionality is? It would be great if you could point me to specific code that I could use as a template.
Thank you,
Alexandra
After some frustrating trial-and-error period, I finally managed to get my code working! It's not beautiful, but it is functional, and now I can start thinking about improving it. Hopefully, some other people will find this information useful ...
The one thing that put me on the right track was the understanding that what needed to be changed was not only in the backbone view code (the one with the new projects form), but also in the corresponding rails models.
For the rails part (Rails 3.2.2), I made sure that the following model files had the necessary information:
project.rb
class Project < ActiveRecord::Base
has_and_belongs_to_many :users
#attr_accessible :name, :description, :users_attributes
#has_many :projects_users, foreign_key: "project_id", dependent: :destroy
#has_many :users, through :projects_users
#accepts_nested_attributes_for :users
end
user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :projects
end
projects_users.rb
class ProjectsUsers < ActiveRecord::Base
belongs_to :project
belongs_to :user
end
I have read in many different places that has_and_belongs_to_many is not the best way to set many-to-many relationships in rails. Nevertheless, I could not get the same functionality using the has_many definition - the commented part in project.rb is the way I tried this different approach. The file user.rb had some corresponding code, which I removed for simplicity.
Now, what I needed to get done in the backbone form view was to send a POST request with a JSON object that the rails projects_controller.rb could recognize. Initially, I tried several POST requests without success (and no errors to guide me). But then, I remembered to have previously implemented a form for teams where users could be added to a particular team (HABTM Checkboxes - there is a railscast for this functionality). After looking at this example, I realized what was needed from my POST request. This is what I wanted to see in the rails server log file:
Started POST "/projects" for 127.0.0.1 at 2012-06-27 00:35:22 +0000
Processing by ProjectsController#create as JSON
Parameters: {"project"=>{"description"=>"with some description", "user_ids"=>["101", "1", "99"], "name"=>"some new project"}}
Backbone relevant files to achieve the above request:
project.js
App.Models.Project = Backbone.Model.extend({
urlRoot: '/projects',
// Default attributes for the project.
defaults: {
description: "",
user_ids: []
},
/* getters */
});
user.js
App.Models.User = Backbone.Model.extend({
/* getters */
});
form.js
App.Views.Projects.Common.Form = Backbone.View.extend({
...
events: {
"submit #new_project_form" : "formSubmit"
},
formSubmit: function(event) {
this.submitted($(event.target));
return false;
},
submitted: function(formElement) {
var newData = this.serializeFormData(formElement);
this.model = new App.Models.Project({
name : newData.name,
description : newData.description
});
this.saveFormData(newData);
return false;
},
serializeFormData: function(formElement) {
var fields = formElement.serializeArray();
var serializedData = {};
$.each(fields, function(index, field) {
serializedData[field.name] = field.value;
});
return serializedData;
},
// THE IMPORTANT PART FOR THE POST REQUEST
saveFormData: function(newData) {
// preserve reference to view for callbacks
var self = this;
var project = this.model;
project.set({
// a list of user ids associated with a project
"user_ids" : this.view_variables.user_ids
});
var project_object = ({
"project" : _.clone(project.attributes)
});
$.ajax({
type: 'POST',
url: '/projects',
data: project_object,
dataType: "json",
success: function() {
self.$el.hide();
self.addNewModelToCollection();
}
});
},
...
});
The code is kind of verbose, and includes some code that is specific to my project. Still, the relevant part is in the saveFormData function, where the jQuery ajax function is used.
In case you have any suggestions, either for the rails or for the Backbone part, please let me know. I will be happy to learn how to improve this solution.
I know it's old post but this looks interesting: http://backbonerelational.org/