In CompoundJS how does database seeding work? - compoundjs

I see that there is a folder for database seeds and a command for it but I couldn't find any documentation on how it works. Can someone help?

This is an old question and the RailwayJS framework is now called CompoundJS but Johnny's advice still works. For anyone looking for a bit more detail this might help.
db/schema.js
var Country = describe('Country', function () {
property('name', String);
set('restPath', pathTo.countries);
});
db/seeds/development/country.js
console.log('Seeding countries...');
var countries = [{
name: 'Canada'
}, {
name: 'USA'
}];
countries.forEach(function(obj) {
Country.create(obj, function(country) {
console.log('Added: ', country);
});
});
Then run:
$ compound seed
Seeding countries...
Added: { name: 'Canada', id: 1 }
Added: { name: 'USA', id: 2 }

I'm sure this is a little late for an answer, but if you haven't found one yet, here goes.
To create seeds:
railway seed harvest
The keyword harvest will invoke the railway app so that it creates seeds based on whatever you currently have in the database. As for where this goes, depending on what environment you have set, eg development, production, etc, it will place you seed files like so:
root/db/seeds/[environment]/[model].coffee
...where [model] is your model (User, Post, Account, etc), and [environment] is your environment (development, test, production, etc).
To seed the database:
railway seed
The documentation is a little light on seeding right now.

Related

Only a node can be linked! Not "undefined"!

I want to put nodes in Gun set.
const Gun = require('gun');
const _ = require('lodash');
require( "gun/lib/path" );
const gun = new Gun({peers:['http://localhost:8080/gun']});
const watchers = [
{
_id: '123',
_type: 'skeleton',
_source: {
trigger: {
schedule: {
later: 'every 1 sec'
}
}
}
},
{
_id: '456',
_type: 'snowman',
_source: {
trigger: {
schedule: {
later: 'every 1 sec'
}
}
}
}
];
const tasks = gun.get('tasks');
_.forEach(watchers, function (watcher) {
let task = gun.get(`watcher/${watcher._id}`).put(watcher);
tasks.set(task);
});
In the end, I receive only the following message. And script stuck in the terminal.
Only a node can be linked! Not "undefined"!
There is nothing on the listener side:
const tasks = gun.get('tasks');
tasks.map().val(function (task) {
console.log('task', task);
});
What is wrong?
The result is received on the listener side only if I change the watchers objects to simpler ones, for example:
_.forEach(watchers, function (watcher) {
let task = gun.get(`watcher/${watcher._id}`).put({id: '123'});
tasks.set(task);
});
Results:
task { _: { '#': 'watcher/123', '>': { id: 1506953120419 } },
id: '123' }
task { _: { '#': 'watcher/456', '>': { id: 1506953120437 } },
id: '123' }
#trex you correctly reported this as a bug, and we got this fixed here: https://github.com/amark/gun/issues/427 .
When a node is referenced, it should not act as if it is undefined. This was a bug.
However, in the future, some people may attempt to link non-node references. As such, I would like to answer the title of your subject (but note, your actual issue has been fixed, and your code should now work correctly in v0.8.8+).
Why do I get "Only a node can be linked!" error?
Say you have a reference to a thing in gun:
var thing = gun.get('alice').get('age');
You may want to add it to a set (otherwise called a table, or list, or collection) like so:
gun.get('list').set(thing);
You will get a "Only a node can be linked!" error. This is annoying! But here is why:
Because age (or any other example data) is a primitive value, adding it to a table would cause it to lose its context. Instead, we can achieve the exact same end result using the following approach:
var person = gun.get('alice').get('age');
gun.get('list').set(thing);
gun.get('list').map().get('age').on(callback);
Now we get back a list of ages, but those ages will always reflect their latest/current realtime context. Had we just added the age to the table, it would no longer have a realtime context.
This is why only nodes can be linked, because any of the data on that node that you were trying to link can just be linked to by traversing via the node. In this case, it was by doing .get('age') after the list. There are a couple really cool things about this:
Bandwidth is saved. GUN will only load the age property from each item in the list, it will not load the rest of the item. It syncs the data you ask about.
Everything is traversable. No matter where your data is in a graph, whether it is a document, a key/value pair, a table, relational data, or anything else, it will always be traversable from its node in the graph. This is possible because it is always the node that is linked, not the primitive data.
Note: What can be frustrating is that you may not know in advance whether a certain gun reference is a node or a primitive, as you could always allow your users to dynamically change the data on that reference. This would require you to handle the error gracefully and do whatever you can best guess the user intended. You can avoid this problem by enforcing a schema on the data in your app. If your app is deployed, we strongly recommend using a schema.
But what if I want the raw data linked, not a realtime context?
Then all you have to do is pass the actual value of the data, not the reference to it. Like so:
gun.get('list').set(thing);
As always, the chatroom is super friendly so come say hi. Please use StackOverflow for asking questions, but notify us in the chatroom. The chatroom is for quick help, and SO is for long standing questions that others would benefit from.
Thanks for asking this question! I hope this answered it, give us a shout if you have any further questions or concerns.

How to retrieve stores based on the store id

I am creating a Memory store as
var someData = [
{id:1, name:"One"},
{id:2, name:"Two"}
];
store = new Memory({
data: someData,
id:”userStore”
});
I was wondering if there is a way to query the Memory store to return the store instance by id. Like
var storePresent = Memory.getById(“userStore”)
something similar to
dijit.registry.byId();
that returns the instance of dijit specified by id
To my knowledge, there is not a store registry as you describe. You will need to code this yourself in your application's controller code.
A store is a simple Object.
You could:
Pass the store manually around your code.
Code a registry AMD module (caution, here be dragons).
The only exception to this rule is if you're already using dojox/app as your controller layer. That has some named store abilities. If not, I would not recommend refactoring to use it.
There's no build-in static repository of memory stores in module dojo/store/Memory. If you need something like that, the easiest way is to write custom factory of memory stores that will hold the static references to all stores that are created:
define(["dojo/store/Memory"], function(Memory){
var repository = {}
return {
getStore: function(id) {
return repository[id]
},
createStore: function(id, params) {
var memory = new Memory(params)
repository[id] = memory
return memory
}
}
});
The usage:
require(["modules/MemoryRepository"], function(MemoryRepository) {
MemoryRepository.createStore("userStore", {data: someData})
...
var userStore = MemoryRepository.getStore("userStore")
})
If you are to create a lot of stores on demand, you should think of deregistering them (removing the references from the factory) as well. Memory issues are probably the reason something like that is not provided out-of-the-box.
Like the other answerers already said, there's no specific repository or registry for stores. However, the dijit/registry can be used to store the reference as well by using the dijit/registry::add() function, for example:
// Add to registry
registry.add(new Memory({
id: "userStore",
data: [{
name: "Smith",
firstname: "John"
}, {
name: "Doe",
firstname: "John"
}]
}));
Then you can retrieve it by using the dijit/registry::byId() function, for example:
// Query the store by using the registry
var person = registry.byId("userStore").query({
firstname: "John"
}).forEach(function(person) {
console.log(person.firstname + " " + person.name);
});
A full example can be found on JSFiddle: http://jsfiddle.net/mn94f/

I am getting a $save() not a function in Angular

I am trying to build a relatively simple web application following tutorials from the book ProAngular. The book examples work fine, but when I try and build my own app, I am getting stuck on a strange error. Here is part of my code:
$scope.dispositionsResource = $resource(dispositionUrl + ":id", { id: "#id" },
{ create: {method: "POST"}, save: {method: "PUT"}, delete: {method: "DELETE"}
});
. . .
$scope.updateDisposition = function (disposition) {
alert("DISPOSITION: "+disposition.name);
disposition.$save();
}
The Create and Delete functions work fine. The updateDisposition method is being called form an HTML form and the correct disposition value is being passed (based on the Alert). But the error I am getting is:
"Error: disposition.$save is not a function"
None of my example code separately defines a save function, the function should be part of the restful service ($resource). Shouldn't it?
Any pointers in the right direction would be greatly appreciated.
Ted
I did end up getting this working. Not totally sure why, but I renamed the Save function to 'Update' and associated it with the PUT functionality.
$scope.dispositionsResource = $resource(dispositionUrl+":id", { id: "#id" },
{ 'create': {method: "POST"}, 'update': {method: "PUT"}
});
$scope.updateDisposition = function (disposition) {
$scope.dispositionsResource.update(disposition);
$scope.editedDisposition = null;
}
calling update rather than save worked. Something seemed to be interfering with using the term 'save'. Like I said, not sure what . . . yet. One of those head-scratchers for me. Thanks to those who tried to assist!
I am learning angular myself, but the first problem I can see with your code is that it doesn't look like you are defining $resource correctly ( fair warning, Angular has a ton of caveats and you may simply be delving into one I am not aware of).
I believe a more straight forward way of doing what you are trying to do is first creating an angular factory for the $resource, like so:
angular.module('yourModuleName')
.factory('disposition', function($resource) {
return $resource('/whatever/url/youwant/:id', {
id: '#id'
})
});
And then from there, declare the factory as a dependency for your controller:
angular.module('yourModuleName')
.controller('yourControllerName', function($scope, disposition) {
$scope.submitForm = function($scope)
disposition.save($scope.nameOfYourModel);
});
One thing to keep in mind is that $resource has all of the methods that you declared by default. From the docs at https://docs.angularjs.org/api/ngResource/service/$resource these are what are available out of the box:
{ 'get': {method:'GET'},
'save': {method:'POST'},
'query': {method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
Personally, I prefer to use the $http service myself. Yes, it is quite a bit more verbose than using $resource but I feel that it is much easier to understand $http when starting with angular than the $resource service. To save yourself from a world of headaches in the future, I highly recommend becoming familiar with the concept of promises in Angular as many of its services make use of them.
Good luck.

What Does bulkCommit Mean In The Context Of Ember's RestAdapter?

Ember Data's DS.RESTAdapter includes a bulkCommit property. I can't find any documentation about what this does/means, other than some vague references to batch committing vs bulk committing.
Initially I assumed it would mean I could only update a single record at a time, but I currently have it set to false, and I'm still able to update multiple records at the same time using:
this.get('store').commit();
So what is the difference between setting bulkCommit to false and setting it to true? In what situation would I use one instead of the other?
The REST adapter supports bulk commits so that you can improve performance when modifying several records at once. For example, let's say you want to create 3 new records.
var tom = store.createRecord(Person, { name: "Tom Dale" });
var yehuda = store.createRecord(Person, { name: "Yehuda Katz" });
var mike = store.createRecord(Person, { name: "Mike Grassotti" });
store.commit();
This will result in 3 API calls to POST '/people'. If you enable the bulkCommit feature
set(adapter, 'bulkCommit', true);
var tom = store.createRecord(Person, { name: "Tom Dale" });
var yehuda = store.createRecord(Person, { name: "Yehuda Katz" });
var mike = store.createRecord(Person, { name: "Mike Grassotti" });
store.commit();
then ember-data will make just one API call to POST '/people' with details for all 3 records. Obviously not every API is going to support this, but if yours does it can really improve performance.
AFAIK there is not documentation for this yet but you can see it working in the following unit test: creating several people (with bulkCommit) makes a POST to /people, with a data hash Array

Sproutcore datasources and model relationships

I currently have a Sproutcore app setup with the following relationships on my models:
App.Client = SC.Record.extend({
name: SC.Record.attr(String),
brands: SC.Record.toMany('App.Brand', {isMaster: YES, inverse: 'client'})
});
App.Brand = SC.Record.extend({
name: SC.Record.attr(String),
client: SC.Record.toOne('App.Client, {isMaster: NO, inverse: 'brands'})
});
When I was working with fixtures my fixture for a client looked like this:
{
guid: 1,
name: 'My client',
brands: [1, 2]
}
And my fixture for a brand looked like this:
{
guid: 1,
name: 'My brand',
client: 1
}
Which all worked fine for me getting a clients brands and getting a brands client.
My question is in regards to how Datasources then fit into this and how the server response should be formatted.
Should the data returned from the server mirror exactly the format of the fixtures file? So clients should always contain a brands property containing an array of brand ids? And vice versa.
If I have a source list view which displays Clients with brands below them grouped. How would I go about loading that data for the source view with my datasource? Should I make a call to the server to get all the Clients and then follow that up with a call to fetch all the brands?
Thanks
Mark
The json you return will mostly mirror the fixtures. I recently had pretty much the same question as you, so I built a backend in Grails and a front end in SC, just to explore the store and datasources. My models are:
Scds.Project = SC.Record.extend(
/** #scope Scds.Project.prototype */ {
primaryKey: 'id',
name: SC.Record.attr(String),
tasks: SC.Record.toMany("Scds.Task", {
isMaster: YES,
inverse: 'project'
})
});
Scds.Task = SC.Record.extend(
/** #scope Scds.Task.prototype */ {
name: SC.Record.attr(String),
project: SC.Record.toOne("Scds.Project", {
isMaster: NO
})
});
The json returned for Projects is
[{"id":1,"name":"Project 1","tasks":[1,2,3,4,5]},{"id":2,"name":"Project 2","tasks":[6,7,8]}]
and the json returned for tasks, when I select a Project, is
{"id":1,"name":"task 1"}
obviously, this is the json for 1 task only. If you look in the projects json, you see that i put a "tasks" array with ids in it -- thats how the internals know which tasks to get. so to answer your first question, you dont need the id from child to parent, you need the parent to load with all the children, so the json does not match the fixtures exactly.
Now, it gets a bit tricky. When I load the app, I do a query to get all the Projects. The store calls the fetch method on the datasource. Here is my implementation.
Scds.PROJECTS_QUERY = SC.Query.local(Scds.Project);
var projects = Scds.store.find(Scds.PROJECTS_QUERY);
...
fetch: function(store, query) {
console.log('fetch called');
if (query === Scds.PROJECTS_QUERY) {
console.log('fetch projects');
SC.Request.getUrl('scds/project/list').json().
notify(this, '_projectsLoaded', store, query).
send();
} else if (query === Scds.TASKS_QUERY) {
console.log('tasks query');
}
return YES; // return YES if you handled the query
},
_projectsLoaded: function(response, store, query) {
console.log('projects loaded....');
if (SC.ok(response)) {
var recordType = query.get('recordType'),
records = response.get('body');
store.loadRecords(recordType, records);
store.dataSourceDidFetchQuery(query);
Scds.Statechart.sendEvent('projectsLoaded')
} else {
console.log('oops...error loading projects');
// Tell the store that your server returned an error
store.dataSourceDidErrorQuery(query, response);
}
}
This will get the Projects, but not the tasks. Sproutcore knows that as soon as I access the tasks array on a Project, it needs to get them. What it does is call retrieveRecords in the datasource. That method in turn calls retrieveRecord for every id in the tasks array. My retrieveRecord method looks like
retrieveRecord: function(store, storeKey) {
var id = Scds.store.idFor(storeKey);
console.log('retrieveRecord called with [storeKey, id] [%#, %#]'.fmt(storeKey, id));
SC.Request.getUrl('scds/task/get/%#'.fmt(id)).json().
notify(this, "_didRetrieveRecord", store, storeKey).
send();
return YES;
},
_didRetrieveRecord: function(response, store, storeKey) {
if (SC.ok(response)) {
console.log('succesfully loaded task %#'.fmt(response.get('body')));
var dataHash = response.get('body');
store.dataSourceDidComplete(storeKey, dataHash);
} ...
},
Note that you should use sc-gen to generate your datasource, because it provides a fairly well flushed out stub that guides you towards the methods you need to implement. It does not provide a retrieveMethods implementation, but you can provide your own if you don't want to do a single request for each child record you are loading.
Note that you always have options. If I wanted to, I could have created a Tasks query and loaded all the tasks data up front, that way I wouldn't need to go to my server when I clicked a project. So in answer to your second question, it depends. You can either load the brands when you click on the client, or you can load all the data up front, which is probably a good idea if there isn't that much data.