Can't set default attribute due to circular reference with Backbone-relational - backbone.js

I'm using Backbone with Backbone-relational. I have two models, Appointment and Client, where a Client can have many Appointments. Here's my Client model definition (in CoffeeScript):
class Snip.Models.Client extends Backbone.RelationalModel
paramRoot: 'client'
relations: [
type: Backbone.HasMany
key: 'appointments'
relatedModel: 'Snip.Models.Appointment'
collectionType: 'Snip.Collections.AppointmentsCollection'
reverseRelation:
type: Backbone.HasOne
key: 'client'
includeInJSON: 'id'
]
defaults:
name: null
phone: null
email: null
notes: null
active: null
class Snip.Collections.ClientsCollection extends Backbone.Collection
model: Snip.Models.Client
url: '/clients'
And here's my Appointment model definition:
class Snip.Models.Appointment extends Backbone.RelationalModel
paramRoot: 'appointment'
defaults:
time_block_type_code: 'APPOINTMENT'
start_time: null
stylist: null
salon: null
client: Snip.Models.Client() # This doens't work
class Snip.Collections.AppointmentsCollection extends Backbone.Collection
model: Snip.Models.Appointment
url: '/appointments'
Here's the problem: since Client references Appointment, I need to include the Appointment file before the Client file so the Snip.Models.Appointment class will exist by the time I reference it. However, Appointment also references Client, so it's kind of a catch-22 situation. I don't know what to do.

First, when using Backbone-Relational don't forget to initialize reverse relations:
Snip.Models.Client.setup()
Second, in your defaults in key client should be attrs for new client model (It will be created by Backbone-Relational). And if you don't have any leave empty hash:
client: {}

Related

Storing messages in new conversation collections; MongoDB

I'm a student working on a chat application for my internship, where I use socket.io.
Right now I am busy thinking of a good way to store the messages send in conversations.
As of now I do the following:
For each conversation between one user and another user, a new collection is made.
On every message sent, the message is stored in the according conversation collection in a single document.
The collections:
Where the document looks as follows:
Now I wonder if there is a good argument to be made to have just one collection "conversations", and store all the messages in multiple documents, where each conversation is a new document.
Creating a new collection for every message is very bad idea instead of that you use a simple schema as given below to store your messages
const conversation_schema = new Schema({
from: {
type: ObjectID,
ref: 'User'
},
to: {
type: ObjectID,
ref: 'User'
},
messageBody: { // body of the message(text body/ image blob/ video blob)
type: String,
},
messageType: { // type of the message(text, mp3, mp4, etc...)
type: String,
},
read: { // to boolean flag to mark whether the to user has read the message
type: Boolean,
default: false,
},
createdAt: { // when was this message goit created
type: Date,
default: new Date(),
},
});
you can fetch the conversation between the two users using the following query
conversations.find({
$or: [
{from: 'user1', TO: 'user2},
{from: 'user2', TO: 'user1},
],
}).populate({ path: 'to', model: User })
.populate({ path: 'from', model: User })
.sort({ createdAt: -1 })

MEAN-stack mongoose, where do functions go?

So I'm fairly new to the mean-stack and I'm using mean.js as a framework.
Using Yeoman I've made a new CRUD module called groups. In a group I want to be able to have an owner, the user who made the group, and a collection of members. According to the mongoose docs I gave the GroupSchema the following structure:
var GroupSchema = new Schema({
name: {
type: String,
default: '',
required: 'Please fill Group name',
trim: true
},
created: {
type: Date,
default: Date.now
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
members: [{type: Schema.ObjectId, ref: 'Member'}]
});
Now, when a group is created the only member will be the owner. I've got the following app structure:
Project:
- app (server side code)
- controllers
- models
- routes
- public (client side code)
- modules
- groups
-controllers
Where do I put the method to add the current user to a certain group? My best guess is that the controller should take care of that, but is it the server or the client side controller?
I wouldn't set it on the client or trust the client. Your server side create function should ignore members completely and just push the current user onto the members array.

What is the difference between idParam, idProperty and clientIdProperty

I am curios about the implementations of the idProperty one in the model and one in the reader
and then a idParam for the proxy and a clientIdProperty on the model
How do we I use them in a right way?
if you get this as a response from the server:
{data: [{userid: 1234, username: "foo"}, {userid: 1235, username: "bar"}]}
so in your UserModel you will have idProperty: "userid" this will tell ExtJS which field to use for functions like getId(), getById(). You could also define this in the reader to share between some models, but usually you should define the idProperty in the model.
idParam seems very unclear to me, it is used only 2 time in the whole framework. is only used to modify the request id parameter send to the server. I don't think this is a parameter you will ever need to change.
clientIdProperty is needed for create operations if proxy.batchActions == true. For example: model.clientIdProperty = "extid" this will send to the server if we create 2 users:
{data: [
{extid: "ext-user-1", username: "foo"},
{extid: "ext-user-2", username: "bar"}
]}
server response:
{data: [
{extid: "ext-user-1", userid: 1234, username: "foo"},
{extid: "ext-user-2", userid: 1235, username: "bar"}
]}
this will tell ExtJS how to map the server ids to the pre-generated ext ids.
(if clientIdProperty is null, ExtJS assumes the same order of request and response for the mapping)

Backbone.js How to retrieve a model in a nested collection?

I have a PizzaType model that has a nested collection of Pizzas. The Pizzas Collection is listed based on the Pizza Type. I would like to be able to click on a pizza in the pizzas collection and display its attributes.
What would be the best way to set the url params dynamically?
The url does not need a route to navigate to for bookmarking and sharing, just to retrieve the specific resource.
I have it so that if someone wants to view the pizza type the url is pizza_type/:id
:id is the id belonging to the Pizza Type (parent model)
I currently have it so if a pizza is clicked on in the Pizzas Collection (that belongs to the Pizza Type Model), the path to the pizza resource is not followed; just a region on the page is updated. The url path is needed so jQuery can get the resource to update that region. The url to the pizza is pizza_types/:pizza_type_id/pizzas/:id Here, the :id is the id belonging to the Pizza Model, and the :pizza_type_id is the foreign key that members of the Pizzas Collection share to group them into the collection, that belong to the Pizzas Type Model.
When I click on the pizza (id = 3), I get "NetworkError: 404 Not Found - http://localhost:3000/pizza_types/3/pizzas"
Here is the Model and Collection Code:
#Pizzeria.module "Entities", (Entities, App, Backbone, Marionette, $, _) ->
class Entities.PizzaType extends Backbone.Model
urlRoot: "pizza_types/"
# creates the nested collection
initialize: ->
#pizzas = new Entities.PizzasCollection
#pizzas.url = #urlRoot + #id + '/pizzas'
#pizzas.fetch
reset: true
parse: (response) ->
response
class Entities.PizzaTypesCollection extends Backbone.Collection
model: Entities.PizzaType
url: 'pizza_types'
parse: (response) ->
response
# Is there a way to pass in a :pizza_type_id and :id params to pass to the url() so
# that the specific pizza model can be retrieved from the collection?
class Entities.Pizza extends Backbone.Model
url: -> "pizza_types/" + 2 + "/pizzas/" + 4 # <-- Hard coded works, but how to set the params dynamically?
parse: (data) ->
data
class Entities.PizzasCollection extends Backbone.Collection
model: Entities.Pizza
url: 'pizzas'
parse: (data) ->
data
Any suggestions? Is this the proper way, I tried to do this as well:
class Entities.Pizza extends Backbone.Model
urlRoot: -> "pizza_types"
# I thought I could pass these params in and fetch the correct pizza model, but not working.
fetch
pizza_type_id: pizza_type_id
id: id
reset: true
parse: (data) ->
data
PizzaType Attributes with example data:
PizzaType: {
id: 2,
name: "Gourmet",
pizzas: [
0: {
id: 4,
pizza_type_id: 2
name: "gourmet pizza 1"
},
1: {
id: 5,
pizza_type_id: 2,
name: "gourmet pizza 2"
}
]
For url in pizza model you can specify an attribute like pizza_type for model in initialize function and change url function like this
class Entities.Pizza extends Backbone.Model
initialize: (options)->
#pizza_type = options.pizza_type if options.pizza_type
url: ->
"pizza_types/" + #pizza_type + "/pizzas/" + #id
parse: (data) ->
data
class Entities.PizzaType extends Backbone.Model
urlRoot: "pizza_types/"
url: ->
#urlRoot+#id+'/pizzas' if #id
initialize: ->
#pizzas = new Entities.PizzasCollection
#pizzas.fetch reset: true
parse: (response) -> response
In PizzasCollection add addOptions so when adding models to collection then backbone add with this default options
class Entities.PizzasCollection extends Backbone.Collection
model: Entities.Pizza
addOptions:
'pizza_type': #id
url: 'pizzas'
parse: (data) -> data
"NetworkError: 404 Not Found -
http://localhost:3000/pizza_types/3/pizzas"
This is a problem with your server, maybe mistyping, or trailing-slash problems or any server problems.
P.S : I recommend using a relational model (with any plugin can do that like BackboneRelationals)

Doctrine/Symfony losing M:N relationships on save

I have what I assume is a configuration problem with my Doctrine schema.yml, but I can't see to strike the right answer here.
I have two tables, BetaMeeting and ProjectTester, that form a many-to-many relationship through BetaMeetingAttendee. Everything works fine, and I can edit a beta meeting for example to include several project testers, and the relationships are all saved correctly. However, when I edit a project tester that already has existing relationships with a beta meeting(s), upon save the M:N relationships are lost. Using Symfony 1.4.13 and the admin generator, and Doctrine 1.2, and the edit page for a project tester makes no mention of the many-to-many relationships, no hidden fields, etc. Could this be the reason, the data's not there so Doctrine removes it? I didn't think it would be necessary to include it.
My schema.yml is as follows, with irrelevant details removed.
BetaMeeting:
connection: doctrine
tableName: BetaMeeting
columns:
id: { type: integer(4), primary: true, autoincrement: true }
project_id: { type: integer(4) }
date: { type: date }
relations:
Project:
local: project_id
foreign: id
foreignAlias: BetaMeetings
ProjectTester:
class: ProjectTester
refClass: BetaMeetingAttendee
foreignAlias: BetaMeetings
BetaMeetingAttendee:
connection: doctrine
tableName: BetaMeetingAttendee
columns:
beta_meeting_id: { type: integer(4), primary: true, autoincrement: false }
project_tester_id: { type: integer(4), primary: true, autoincrement: false }
relations:
BetaMeeting:
foreignAlias: BetaMeetingAttendees
ProjectTester:
foreignAlias: BetaMeetingAttendees
ProjectTester:
connection: doctrine
tableName: ProjectTester
columns:
id: { type: integer(4), primary: true, autoincrement: true }
tester_id: { type: integer(4) }
project_id: { type: integer(4) }
relations:
Tester:
local: tester_id
foreign: id
foreignAlias: Projects
Project:
local: project_id
foreign: id
foreignAlias: ProjectTesters
Any clue as to why the relationships get cleared out after an edit which is concerned only with the immediate attributes of the ProjectTester object?
If you have a field defined in the Form but you excluded it from the generator.yml it's like submitting an empty field and therefore it clears the relations.
You have to unset that field in the Form.class so the field retains the current values.
public function configure()
{
unset($this['beta_meeting_list']); // or the correct value
}

Resources