adding models to backbone collections - ruby-on-rails-4

I have a rails app with 4 Model classes, with multiple instances in each table. I have created backbone Model and Collection classes in CoffeeScript to match. I can successfully load all of the collections and can render them in views. So far, so good. Here is one of my collections, with its associated model:
class window.CoffeeWater.Collections.Histories extends Backbone.Collection
url: '/api/histories'
model: History
class window.CoffeeWater.Models.History extends Backbone.Model
I need to be able to create a History model object, and then add it to the Histories collection. The documentation states that I have to set a 'collection' property when creating my new model, in order for it to get the 'url' property from the collection. My problem is that I can't seem to set the 'collection' property value correctly, because the url property does not get set on the model instance
attributes = {'start_time': new Date (1434740259016), 'stop_time': new Date (1434740259016 +(86400*1000)), 'valve_id': 2}
options = { collection: window.CoffeeWater.Collections.Histories }
history = new window.CoffeeWater.Models.History(attributes, options)
window.CoffeeWater.Objects.Collections.Histories.add(history)
Inspecting the resulting 'history' object does not show the same attributes that exist in models already in the collection, and the url property is missing.
I am currently at a loss. Does anyone have an example on how to do this? The backbone.js docs do not show any relevant examples.

The way the url in model is defined like this.
If there is a url property in model.
class window.CoffeeWater.Models.History extends Backbone.Model
url:'/api/history/1'
Then when model.fetch(), it will call that url. If this property is not found, it will see if the associated collection does have a 'url'. You try to set this collection variable.
What you are missing is this. This
class window.CoffeeWater.Collections.Histories extends Backbone.Collection
is actually a definition of a class. It is not an object yet. You need to initialize it, like you do in java. so
var historyCollection=new window.CoffeeWater.Collections.Histories()
Now you have a collection object. When you do
historyCollection.add(history);
The "collection" of model is automatically set to the "historyCollection" object, which contains a 'url'. So in fact, you do not need to manually put this in the option.
basically
attributes = {'start_time': new Date (1434740259016), 'stop_time': new Date (1434740259016 +(86400*1000)), 'valve_id': 2}
var historyCollection=new window.CoffeeWater.Collections.Histories()
var history = new window.CoffeeWater.Models.History(attributes)
historyCollection.add(history)

Related

Find the class name of a relation from the instance of a model in ember JS

I have foo an instance of the ember-data model thing. thing.js has the following property :
owner: DS.belongsTo('user')
If I have foo with an empty owner, how can I, with only foo and the 'owner' string, retrieve the value 'user' representing the model of the owner relation?
EDIT: I want to allow my select-relation component to works with relations where the name is different from the class name
It sounds like you have some work to do to finish setting up your relationships. Have a read through this page of the guides.
If the relationships are set up correctly, to get the associated user, you should be able to do foo.owner. This assumes that users are already present in the store. I recommend using the Ember Inspector browser plugin to debug the relationships.
This looks like a use case for typeForRelationship.
In your example you should be able to do something like
store.modelFor('thing').typeForRelationship('owner', store);
If you don't like that approach you can use the belongsTo reference API, where you use the meta data from the relationship to get the type
foo.belongsTo('owner').type
The only thing with that approach is that the type property may not be public API and possible (though unlikely) to change at some point.
It seems I can do the following :
this.get('model').get('_internalModel._relationships.initializedRelationships.'+this.get('relation')+'.relationshipMeta.type')
model being an instance and relation the string of the relation name, it correctly return the model of the relation.
EDIT : a better solution not using private API courtesy from the ember discord :
function getRelatedModelName(record, relationName){
let ParentModelClass = record.constructor;
let meta = get(ParentModelClass, 'relationshipsByName').get(relationName);
return meta.type;
}

Can i hide the query params from the URL?

In my Ember.js Application, I am dealing with query params for list updates. I have one strange use case, in which I don’t the URL to be updated with certain query params. How can I achieve this?
I assume you want to reload your model with parameters that are different than the ones in your application route? And you keep your application route parameters synced using queryParams?
In your route's model function you can filter your model data by the same query params (that appear in the address bar) but you can add some logic that extracts additional parameters either from the controller or other place and these parameters the data fetching query. Example:
model: function(queryParams) {
var params = queryParams;
params.additional_filter = this.controllerFor('mycontroller').get('additional_filter');
return this.store.find('mymodel', params);
}
Also if you want to explicitly reload the model you will need to call Router.refresh() function.

What is the difference between 'model.property' vs 'property' for computed property?

Going throught the getting started tutorial for ember js and I am somewhat confused by what the differences are in doing
function(){}.property('model.isCompleted')
and
function(){}.property('isCompleted')
Specifically, what is the model for?
The model is just another property, but instead of being a primitive such as a string or a number its an object.
For:
model = {
prop1: 'fi',
prop2: 'fai',
prop3: 'fo',
prop4: 'fu'
}
If you do this: function(){}.property('model.prop3') your computed property will be updated only when prop3 changes.
If you do this: function(){}.property('model') your computed property will be updated when model changes.
And model is a property in your controller set by the route you are in.

Django, Tastypie and retrieving the new object data

Im playing a little bit with heavy-client app.
Imagine I have this model:
class Category(models.Model):
name = models.CharField(max_length=30)
color = models.CharField(max_length=9)
Im using knockoutjs (but I guess this is not important). I have a list (observableArray) with categories and I want to create a new category.
I create a new object and I push it to the list. So far so good.
What about saving it on my db? Because I'm using tastypie I can make a POST to '/api/v1/category/' and voilà, the new category is on the DB.
Ok, but... I haven't refresh the page, so... if I want to update the new category, how I do it?
I mean, when I retrieve the categories, I can save the ID so I can make a put to '/api/v1/category/id' and save the changes, but... when I create a new category, the DB assign a id to it, but my javascript doesn't know that id yet.
in other words, the workflow is something like:
make a get > push the existing objects (with their ids) on a list > create a new category > push it on the list > save the existing category (the category doesnt have the id on the javacript) > edit the category > How I save the changes?
So, my question is, what's the common path? I thought about sending the category and retrieving the id somehow and assign it to my object on js to be able to modify it later. The problem is that making a POST to the server doesn't return anything.
In the past I did something like that, send the object via post, save it, retrieve it and send it back, on the success method retrieve the id and assign it to the js object.
Thanks!
Tastypie comes with an always_return_data option for Resources.
When always_return_data=True for your Resource, the API always returns the full object event on POST/PUT, so that when you create a new object you can get the created ID on the same request.
You can then just read the response from your AJAX and decode the JSON (i dont know about knockout yet).
see the doc : http://readthedocs.org/docs/django-tastypie/en/latest/resources.html?highlight=always_return_data#always-return-data
Hope this helps

django admin filter tweaking

I want to use django's admin filter on the list page.
The models I have are something like this:
class Location(model):
name = CharField()
class Inquiry(Model):
name = CharFiled()
location = ManyToManyField(Location)
Now I want to filter Inquiries, to display only those that contain relation to specific Location object. If I use
class InqAdmin(ModelAdmin):
list_filter = ['location', ]
admin.site.register(Inquiry, InqAdmin)
the admin page displays me the list of all Locations and allows to filter.
What I would like to get, is to get list of only those locations that have some Inquiries in relation to them (so I don't ever get the empty list result after filtering).
How can this be done?
You could create a custom manager for Locations that only returns Locations that have an Inquiry associated with them. If you make this the default manager, the admin will use it.
Only caveat is that you'll need create another manager that returns all Locations and use that in the rest of your app whenever you want to retrieve Locations that don't have an associated Inquiry.
The managers section in the Django docs is quite good, and should be all you need to get this set up.
EDIT:
sienf brings up a good point. Another way to accomplish this would be to define a subclass of django.contrib.admin.SimpleListFilter, and write the queryset method to filter out Inquiries with empty Locations. See https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter