How to interact with a join table in bookshelf and knex? - mysql

I want to create an entry in a join table using bookshelf. I followed the instructions on the bookshelf website here. (Models instantiation with bookshelf and tables creation with knex).
Is there a way, upon creation of a new Book, to add values to the authors_books table WITHOUT creating an authors_books model/collection?
What should I add to this:
//Books references the Books collection that holds the Book models
var book = new Book({
title: title,
base_url: req.headers.origin
});
book.save().then(function(newBook) {
Books.add(newLink);
res.send(200, newBook);
});

Yes, of course, it's quite simple.
You need two models, Book and Author. Both have belongsToMany relationship defined and withPivot as well. withPivot lists the attributes that are in the junction table, see more here: http://bookshelfjs.org/#Model-withPivot
Afterwards, you call updatePivot, to update the attributes that are in author_book table only.

Related

Parse.com many-to-many with attributes

I have a many-to-many relation between "Ingredient" and "Recipe". I know I can add and remove object from the relation using
var Recipe = Parse.Object.extend("Recipe");
var Ingredient = Parse.Object.extend("Ingredient");
var recipe = new Recipe();
var ingredient = new Ingredient();
ingredient.id = "abcDef1234"; //random
var recipe_ingredients = recipe.relation("recipe_ingredients");
recipe_ingredients.add(ingredient);
But this only adds the ingredient. How do I also store a field like "quantity" along with each ingredient added? (Like extra attributes on a pivot table?)
Thanks!
You can't. This is one of Parse's many limitations. You'll have to abandon the builtin relations model, create your own join table. That is, create a new object type which has two pointers: the first, the source object; the second, the target. This forms the relation. You can then add fields on this table to act as attributes on the relationship. If you want, you can keep a pointer from the object that originally held the relation, targeting the join table entry.
Of course, once you realise that this doubles the number of requests you're using (each database hit is a "request" apparently), then you start to realise that the Parse database model coupled with their charging model scales about as well as building skyscrapers from matchsticks.

sqlalchemy relations and query on relations

Suppose I have 3 tables in sqlalchemy. Users, Roles and UserRoles defined in declarative way. How would one suggest on doing something like this:
user = Users.query.get(1) # get user with id = 1
user_roles = user.roles.query.limit(10).all()
Currently, if I want to get the user roles I have to query any of the 3 tables and perform the joins in order to get the expected results. Calling directly user.roles brings a list of items that I cannot filter or limit so it's not very helpful. Joining things is not very helpful either since I'm trying to make a rest interface with requests such as:
localhost/users/1/roles so just by that query I need to be able to do Users.query.get(1).roles.limit(10) etc etc which really should 'smart up' my rest interface without too much bloated code and if conditionals and without having to know which table to join on what. Users model already has the roles as a relationship property so why can't I simply query on a relationship property like I do with normal models?
Simply use Dynamic Relationship Loaders. Code below verbatim from the documentation linked to above:
class User(Base):
__tablename__ = 'user'
posts = relationship(Post, lazy="dynamic")
jack = session.query(User).get(id)
# filter Jack's blog posts
posts = jack.posts.filter(Post.headline=='this is a post')
# apply array slices
posts = jack.posts[5:20]

Multilingual text fields with SQLAlchemy

I am currently evaluating SQLAlchemy for a project. Here is my schema:
a LANGUAGE table, with a row for each language supported
a TRANSLATION table with (ID, LANGUAGE_ID, STR)
various tables will, instead of storing text, store TRANSLATION_IDs, for example, BOOK(ID, TITLE_TRANSLATION_ID, ABSTRACT_TRANSLATION_ID)
Now, assuming each request has the current language ID available (for example, through a thread variable...), I would need SQLAlchemy to automatically join the TRANSLATION table, and thus have text fields in the current language. Something like:
class Book(Base):
id = Column(Integer, primary_key=True)
title = TranslatableText()
abstract = TranslatableText()
When retrieving, the ORM would automatically join to the TRANSLATION table with the current language ID, and my_book.title would give me the title in the current language.
I also need this to work across relations: if a class contains foreign keys to other classes that also contain translatable text fields, I would ideally like those to be retrieved too.
Lastly, I would also need to be able to get to the TRANSLATION_ID for each field, for example through my_book.title_translation_id.
I am not expecting a complete solution, but I'd like to know if something like this is feasible, and where to start.
You have to use the concept of http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative.html#mixin-and-custom-base-classes
Create one top level class and write some funciton like read, write and create. Always call that function to create or read data from the database.
If you dont want to implement the mixin classes then also you can use event http://docs.sqlalchemy.org/en/latest/orm/events.html#sqlalchemy.orm.events.MapperEvents.translate_row

Update object in the Entity framework that have relations

I am trying to update an whole entity object with relations in database in entity framework , and without success.
I am trying to do something like this:
var objectToUpdate = DAL.GetProduct(id);
// then I have collection of Comments related to this product.
// and I want to update th whole collection
objectToUpdate.Comments.Clear();
foreach(var newComment in comments){
objectToUpdate.Comments.Add(newComment);
}
What I am getting in database is duplication of all related to my products comments.
Please suggest how to update related Entities properly.
Thanks.
If you want to update a relationship between objectToUpdate and a collection of comments which are already existing in the database you need to attach the comments to context before you add them to the Comments collection of your objectToUpdate. Otherwise EF will create new comment rows in the database:
var objectToUpdate = DAL.GetProduct(id);
objectToUpdate.Comments.Clear();
foreach(var newComment in comments)
{
context.Comments.Attach(newComment);
objectToUpdate.Comments.Add(newComment);
}

Using LINQ and Entity how do I return values of a many-to-many relationship

I have two entities, Account and Subscription with a many-to-many association between them. I can't seem to find in the tutorials anywhere how to do the following:
I want to find all the Accounts with a Subscription of type x. If I wasn't using the Entity framework I could join to the AccountSubscription table, but that isn't accessible via Entity. Do I have to create a special entity if I need to query on a many-to-many relationship?
EF should create a navigation property for a many-to-many relationship. Then you should be able to do something like this:
var accounts = from a in Accounts
where a.Subscriptions.Any(s => s.SubscriptionType == "something")
select a;
For example, I have a simple db with a many to many relationship between Products and Groups:
And EF creates the association in the model:
So I can create a query like this (here including the Groups so I can see the Category):
What about something like this:
List<Accounts> myAccounts = //get accounts;
foreach(Accounts a in myAccounts)
{
foreach(Subscriptions s in a)
{
//add it to a global list?
}
}