sailsjs one-way-association implementation - sails.js

i follow this link and trying to show the data
http://sailsjs.org/documentation/concepts/models-and-orm/associations/one-way-association
but i got the error "Unknown column 'shop.building_detail' in 'field list' "
Is it the sails bug or something i did wrong ?
there are my database design and my code in below
database design
Shop model:
module.exports = {
autoPK:false,
attributes : {
shop_id : {
primaryKey : true,
type : 'int',
unique: true,
columnName : 'shop_id'
},
shop_floor : {
type : 'string'
},
shop_room : {
type : 'string'
},
shop_build : {
type : 'int',
foreignKey:'true'
},
building_detail : {
model : 'building'
}
}
};
Building model:
module.exports = {
autoPK:false,
attributes : {
build_id : {
primaryKey : true,
type : 'int',
unique: true,
columnName : 'build_id'
},
build_name : {
type : 'string'
},
build_address : {
type : 'string'
},
build_latitude : {
type : 'float'
},
build_longitude : {
type : 'float'
},
build_visit_count : {
type : 'int'
},
build_status : {
type : 'string'
},
build_status_last_update_time : {
type : 'time'
}
}
};

With your database design, your Shop model could look like this:
Shop.js
module.exports = {
autoPK:false,
attributes : {
shop_id : {
primaryKey : true,
type : 'int',
unique: true,
columnName : 'shop_id'
},
shop_floor : {
type : 'string'
},
shop_room : {
type : 'string'
},
shop_build : {
model: 'Building'
}
}
};
Sails.js automatically associates shop_build with the primary key of the Building model.
When you create a shop, just specify the building id as the value for shop_build:
Shop.create({
shop_floor: "Some floor",
shop_room: "Some room",
shop_build: 8 // <-- building with build_id 8
})
.exec(function(err, shop) { });
And when you perform shop queries, you can populate the building details:
Shop.find()
.populate('shop_build')
.exec(function(err, shops) {
// Example result:
// [{
// shop_id: 1,
// shop_floor: 'Some floor',
// shop_room: 'Some room',
// shop_build: {
// build_id: 8,
// build_name: 'Some building',
// ...
// }
// }]
});
See Waterline documentation on associations for more details.

Related

[mongodb]How to save a document and automatically increase a field of it?

I need to save or insert a new record into my mongo database. I hope the field "userid" of it can automatically increase by 1. Is it possible to do it in mongodb?
Schema
generalUserApplication: {
userid: Number, // 1
lora: [
{},
{}
]
}
Here's the way from the mongo tutorial.
You need to create new collection counters in your db.
function getNextSequence(db, name, callback) {
db.collection("counters").findAndModify( { _id: name }, null, { $inc: { seq: 1 } }, function(err, result){
if(err) callback(err, result);
callback(err, result.value.seq);
} );
}
Then, you can use getNextSequence() as following, when you insert a new row.
getNextSequence(db, "user_id", function(err, result){
if(!err){
db.collection('users').insert({
"_id": result,
// ...
});
}
});
I have use another package named 'mongoose-sequence-plugin' to generate sequence which is auto-incremented by 1.
Here I am posting code that I have tried for same problem. Hope it will help.
Schema :
var mongoose = require('mongoose');
var sequenceGenerator = require('mongoose-sequence-plugin');
var Schema = mongoose.Schema;
var ProjectSchema = new Schema({
Name : { type : String, required: true },
Description : { type : String, required: true },
DetailAddress : { type : String, required: true },
ShortAddress : { type : String, required: true },
Latitude : { type : Number, required: true },
Longitude : { type : Number, required: true },
PriceMin : { type : Number, required: true, index : true },
PriceMax : { type : Number, required: true, index: true },
Area : { type : Number, required: true },
City : { type : String, required: true }
});
ProjectSchema.plugin(sequenceGenerator, {
field: 'project_id',
startAt: '10000001',
prefix: 'PROJ',
maxSaveRetries: 2
});
module.exports = mongoose.model('Project', ProjectSchema);
This will create projects collection with parameter project_id starting from PROJ10000001 and on wards. If you delete last inserted record then this package reads the current last entry of field project_id and next id is assigned by incrementing current id.

How to auto populate nested associations of sails blueprint for url /model/<id>/association

I have two models Users and Chat with many to many association.
User.js
module.exports = {
attributes: {
name: {
type : 'string'
,required : true
},
email:{
type : 'string'
,email : true
,required: true
,unique : true
},
enpassword : {
type: 'string'
},
online : {
type: 'boolean',
defaultsTo: false
},
socketid: {
type: 'string'
},
chats : {
collection: 'chat',
via: 'users',
dominant: true
}
};
Chat.js
module.exports = {
attributes: {
messages : {
collection: 'message',
via : 'chat',
dominant : true
},
users : {
collection: 'user',
via : 'chats'
},
}
};
When I call sails blueprint /user/1/chats I am getting list of chats but users association of each chat is not populated.
How can I achieve this from Sails queries ?
Great question. Here is a really easy way to do this.
First, require the following module.
var nestedPop = require('nested-pop');
Next, run your query.
getPopulatedUsers = function(req, res) {
User.find()
.populate('chats')
.then(function(users) {
return nestedPop(users, {
chats: [
'messages',
'users' // I actually wouldn't recommend populating this since you already have the users
]
}).then(function(users) {
console.log(users);
res.json(users);
});
});
}
More docs on this can be found at the following link.
https://www.npmjs.com/package/nested-pop

Set store dynamic on a combobox

Hi,
I have two combo boxes. The value of second combo box depends on first combo select. The user does select the first combo then the store of second will be set accordingly.
Here are my two Combos:
Combo 1
items:[
{
xtype : 'combo',
name : 'cmbSATopFacility',
labelStyle : 'color: black; font-weight: bold; width: 250px; padding: 10;',
labelSeparator : "",
id : 'cmbSATopFacility',
width : 250,
fieldLabel : 'Top MGMT Entity',
triggerAction : 'all',
store : Ext
.create(
'Ext.data.Store',
{
id : 'store',
fields : [
{
name : 'id',
type : 'integer',
},
{
name : 'name'
} ],
remoteGroup : true,
remoteSort : true,
proxy : {
type : 'rest',
url : 'pmsRest/facilities?sub_facility_id=-3',
reader : {
root : "facilityMaster",
idProperty : 'id'
}
},
autoLoad : true
}),
displayField : 'name',
valueField : 'id',
multiSelect : false,
typeAhead : true,
listeners : {
change : function(combo) {
/// code to convert GMT String to date object
n();
Ext.getCmp('cmbSAMedFacility').getStore().load();
}
},
allowBlank : false,
//enableKeyEvents : true,
},
Combo 2
{
xtype : 'combo',
name : 'cmbSAMedFacility',
labelStyle : 'color:black;font-weight:bold;width:250px;padding:10;',
labelSeparator : "",
id : 'cmbSAMedFacility',
width : 250,
fieldLabel : 'Institution',
triggerAction : 'all',
store : medfacility,
displayField : 'name',
valueField : 'id',
multiSelect : false,
typeAhead : true,
//disabled: true,
listeners : {
click : function(combo) {
alert("hjdfhcsdj");
n();
Ext.getCmp(this).getStore().load();
}
},
allowBlank : false,
//enableKeyEvents : true,
},
]
Code to set store
var medfacility = loadFacility();
function loadFacility(){
topApp = Ext.getCmp('cmbSATopFacility').getValue( );
alert(topApp);
var urL = 'pmsRest/facilities?sub_facility_id='+topApp ;
alert(urL);
var store = Ext.create('Ext.data.Store', {
id : 'store',
fields : [
{
name : 'id',
type : 'integer',
},
{
name : 'name'
} ],
remoteGroup : true,
remoteSort : true,
proxy : {
type : 'rest',
url : urL,
reader : {
root : "facilityMaster",
idProperty : 'id'
}
},
autoLoad : true
});
return store;
}
I tried to get the values in the second combo but it didnĀ“t work.
WE CAN USE ONLY
listeners : { change : function(combo) { Ext.getCmp('cmbSAMedFacility').bindStore(n());}},
I think you need describe a store for a second combobox, but without data (empty array).
And fill data for that store when you need by using loadData method.
Hope this helps.

extjs4 proxy rest multiple request issue

Hi I am encountering a wierd behavior with my application:when I modify an item and then my proxy doas a put request, the first time is ok, the second time it sends two requests: the first with the data of the previous one, the second one with the actual data, the third time it sends three requests, onmy system it is not a big issue, because at end I get the right value on my database, but on my customer's system the result it is not always correct. Then I would like to remove this behavior.
this is my store:
Ext.create('Ext.data.Store',
{
storeId: 'bbCompaniesStore',
model:'Company',
pageSize: pageSize,
proxy:
{
idProperty : '_id',
type: 'rest',
url: 'data/companies/',
autoload: true,
noCache: true,
sortParam: undefined,
actionMethods:
{
create : 'PUT',
read : 'GET',
update : 'POST',
destroy: 'DELETE'
},
reader:
{
type: 'json',
root: 'data',
totalProperty: 'total'
},
},// proxy
listeners: {
exception: function(proxy, response, operation) {
Ext.gritter.add({
title: MongoVision.text['action.' + operation.action] || operation.action,
text: (operation.error ? operation.error.statusText : null) || MongoVision.text.exception
});
// Ext JS 4.0 does not handle this exception!
switch (operation.action) {
case 'create':
Ext.each(operation.records, function(record) {
record.store.remove(record);
});
break;
case 'destroy':
Ext.each(operation.records, function(record) {
if (record.removeStore) {
record.removeStore.insert(record.removeIndex, record);
}
});
break;
}
}
}
}
);
this is my model:
Ext.define('Company',
{
extend: 'Ext.data.Model',
fields: [
{
name : 'id',
type : 'string'
},
{
name :'firm',
type : 'string',
allowBlank: false
},{
name : 'p'
},
{
name: 'linee'
},
{
name : 'c'
},
{
name : 'data',
type: 'date'
},
{
name :'note'
},
{
name :'paese'
},
{
name : 'email'
},
{
name : 'telefono'
},
{
name : 'type'
},
{
name : 'website'
},
{
name : 'session_id'
},
{
name : 'group_id'
}
],
proxy : {
type : 'rest',
url : 'data/companies/'
}
}
);
after googling around I found a similar issue for extjs3, with no solution, I think it is strange that after so long time, there is no yet a solution; it should work now
I faced the same issue, resolved it by simply passing
batchActions: true when creating the Proxy. The default behavior for 'rest' proxies is to turn off batching.... (See extjs/src/data/proxy/Rest.js)

Local Storage implementation

I am trying to load a form and save the form details in the local storage.
I am not quite sure how i should go about it.
Any suggestions are helpful.
This is my form whose data i need to save.
var count = 3; // count to control the maximum number of selections
//Configuration class definition
Ext.define("InfoImage.view.configure.Settings",{
extend : 'Ext.form.Panel',
requires : [
//'InfoImage.view.workItemPanel',
'Ext.TitleBar', 'Ext.field.Text', 'Ext.field.Toggle',
'Ext.field.Select', 'Ext.layout.HBox',
'Ext.field.Number', 'Ext.field.Checkbox',
'Ext.form.FieldSet', 'Ext.field.Password',
'Ext.field.Url' ],
xtype : 'settingsPanel',
id : 'settings',
config : {
//store:'configStore',
scrollable : {
direction : 'vertical'
},
items : [
{
xtype : 'toolbar',
ui : 'dark',
docked : 'top',
title : 'InfoImage Settings',
items : [
{
xtype : 'button',
iconCls : 'delete2',
iconMask : true,
ui : 'normal',
id : 'homeSettingbtn'
},
{xtype: 'spacer'},
{
xtype : 'button',
//text:'Save',
iconCls : 'save_fin',
iconMask : true,
ui : 'normal',
id : 'savebtn',
handler : function() {
//console.log('hi');
//var form = Ext.getCmp('settings').getValues().validate();
//form.validate();
// var errors = form.validate();
//console.log(form.isValid());
}
},
{
xtype : 'button',
//text:'Default',
iconCls : 'default',
iconMask : true,
ui : 'normal',
handler : function() {
var form = Ext.getCmp('settings');
form.reset();
}
}
]
},
{
//fieldset defined for the Server Configuration details to be entered.
xtype : 'fieldset',
title : 'Server Configuration',
defaults : {
xtype : 'selectfield',
labelWidth : '30%',
},
items : [
{
xtype : 'urlfield',
name : 'servname',
id : 'servname',
label : 'Server Name',
labelWidth : '30%'
},
{
xtype : 'numberfield',
id : 'port',
name : 'port',
label : 'Port',
value : '80',
labelWidth : '30%'
},
{
xtype : 'selectfield',
name : 'protocol',
id : 'protocol',
label : 'Protocol',
labelWidth : '30%',
usePicker : false,
handler : function() {
},
options : [ {
text : 'HTTP',
value : 'HTTP'
}, {
text : 'HTTPS',
value : 'HTTPS'
}
]
}
]
},
{
//fieldset defined for the User Configuration details to be entered.
xtype : 'fieldset',
title : 'User Configuration',
items : [ {
xtype : 'textfield',
name : 'username',
id : 'username',
label : 'User Name',
labelWidth : '30%'
}, {
xtype : 'passwordfield',
name : 'password',
id : 'password',
label : 'Password',
labelWidth : '30%'
}, {
xtype : 'textfield',
id : 'domain',
name : 'domain',
label : 'Domain',
labelWidth : '30%'
} ]
},
{
//fieldset defined for the Work Item display attributes to be checked.
xtype : 'fieldset',
id:'check',
title : '<div class="appconfig"><div>App Configuration</div>'
+ '<br /><div style="font-size: 14px;font-weight: bold;">Work Item display attributes</div></div>',
defaults : {
xtype : 'checkboxfield',
labelWidth : '30%'
},
items : [
{
name : 'domainname',
id : 'c1',
value : 'domainname',
label : 'Domain Name',
listeners : {
check : function() {
var obj1 = Ext
.getCmp('c1');
if (obj1.isChecked()) {
obj1.check();
count++;
if (count > 3) {
Ext.Msg
.alert(
'InfoImage',
'Please choose only three fields',
Ext.emptyFn);
obj1.uncheck();
count--;
}
}
},
uncheck : function() {
var obj1 = Ext
.getCmp('c1');
if (!obj1.isChecked()) {
obj1.uncheck();
count--;
}
}
}
},
{
name : 'objectid',
id : 'c2',
value : 'objectid',
label : 'Object ID',
checked : 'true',
listeners : {
check : function() {
var obj2 = Ext
.getCmp('c2');
if (obj2.isChecked()) {
obj2.check();
count++;
if (count > 3) {
Ext.Msg
.alert(
'InfoImage',
'Please choose only three fields',
Ext.emptyFn);
obj2.uncheck();
count--;
}
}
},
uncheck : function() {
var obj2 = Ext
.getCmp('c2');
if (!obj2.isChecked()) {
obj2.uncheck();
count--;
}
}
}
},
{
name : 'servername',
id : 'c3',
value : 'servername',
label : 'Server Name',
listeners : {
check : function() {
var obj3 = Ext
.getCmp('c3');
if (obj3.isChecked()) {
obj3.check();
count++;
if (count > 3) {
Ext.Msg
.alert(
'InfoImage',
'Please choose only three fields',
Ext.emptyFn);
obj3.uncheck();
count--;
}
}
},
uncheck : function() {
var obj3 = Ext
.getCmp('c3');
if (!obj3.isChecked()) {
obj3.uncheck();
count--;
}
}
}
},
{
name : 'workitemname',
id : 'c4',
value : 'workitemname',
label : 'WorkItem Name',
checked : 'true',
listeners : {
check : function() {
var obj4 = Ext
.getCmp('c4');
if (obj4.isChecked()) {
obj4.check();
count++;
if (count > 3) {
Ext.Msg
.alert(
'InfoImage',
'Please choose only three fields',
Ext.emptyFn);
obj4.uncheck();
count--;
}
}
},
uncheck : function() {
var obj4 = Ext
.getCmp('c4');
if (!obj4.isChecked()) {
obj4.uncheck();
count--;
}
}
}
} ]
},
{
//fieldset defined for the App Subtitle to be entered.
xtype : 'fieldset',
items : [ {
xtype : 'textfield',
name : 'apptitle',
id : 'apptitle',
label : 'App Subtitle',
labelWidth : '30%',
value : 'Mobile Client Work Manager'
} ]
}
]
}
});
Do i need to create model and store? how do i get the values and store it?
Here's how you declare your store :
Ext.define('App.store.Items', {
extend: 'Ext.data.Store',
requires:"Ext.data.proxy.LocalStorage",
config: {
proxy: {
type: 'localstorage',
id: 'application-items'
},
autoLoad: true,
model: 'App.model.Item',
}
});
Here's the model
Ext.define('App.model.Item', {
extend: 'Ext.data.Model',
config: {
fields: [
'field1',
'field2'
]
}
});
Then, to add an item to the store :
store.add({field1:'value1',field2:'value2'});
store.sync();
Hope this helps
http://nareshtank.blogspot.in/2012/03/html-5-localstorage-usefull-methods.html