Using Mongo Update and $set to insert field (throwing error) - ruby-on-rails-3

Ok, this is probably a stupid question but I have been reading and trying different queries and for some reason I cannot get this to work without throwing an error. This is my first time working with MongoDB and it is in an RoR project. We set up charities to have a twitter handle field, but it was not put into the model originally. So we populated the DB with charities, but now none of them have the twitter handle field. I added it to the model so now all others created will have it.
My issue is when I try to update the charities already in my DB I keep getting an error pointing at $set:
namespace :add_tw_handles_fields_2013_6_13 do
desc "add_tw_handle"
task :add_tw_handle => :environment do |t, args|
# db.charity.update( { featured: false }, { $set: { tw_handle : "test"}}, false, true)
# got your 6
Charity.update({ },
{
$set: { "tw_handle": "test"}
},
{ multi: true }
})
end
end
I tried the 2 synax calls above, I was reading in these 2 docs http://docs.mongodb.org/manual/reference/method/db.collection.update/ http://docs.mongodb.org/manual/core/update/#Updating-The%24positionaloperator.
I always get this error tho:
add_tw_handles_fields_2013_6_13.rake:16: syntax error, unexpected ':', expecting tASSOC
$set: {
As far as I can tell that is the correct syntax. I am running this in the script so I don't think I need the db. before my Model name (as shown in the uncommented update) right? I am new to this, but I literally copied and pasted the example and filled out my info, and nothing. I then tried adding a query, but there is never an error until it gets to $set: and I have no idea why. It is exactly as is shown in the Mongo docs linked above.
Any insight into what my issue would be greatly appreciated.
Thanks,
Alan

The error you're getting is from Ruby, not MongoDB, because you're trying to use MongoDB's JSON syntax inside of Ruby, which Ruby does not like. :) Your update query looks fine but you need to translate it to Ruby syntax which is a bit different.
coll.update( { }, { "$set" => { "tw_handle" => "test" } } );
will work assuming coll is your Collection object.
See here for a good tutorial (written by the MongoDB Ruby team) on using the Ruby driver.

Ok so after looking around and talking to the other dev on this project this is what I have found:
Inside a rails script you want to access the objects through rails not the mongoDB directly:
Following example is for running a script from within lib/tasks
Uses Rails activerecord to update the entry through the framework
m = ModelName.find("51b610972f52760fcc003331")
m.update_attributes( :attribute_name => "what you want to assign" )
m.save
Finds the object that has the id given from your model in rails (accesses mongo db directly)
object = ModelName.find({
"$in" => {
"_id" => "51b610972f52760fcc003331"
}
})
object.first.update_attributes(:attribute_name => "what you want to assign")
From within the console
Within the rails console you can use the first segments syntax using the activerecord models to access the objects you are querying for. But if you want to go directly into the mongo console the syntax is slightly different then above.
after going to the root directory of your project launch mongo in the console and find an object from one of your collections based on its id:
>mongo
>show dbs
>use dbsname
>show collections
>db.collection_name.find({ _id: { $in: [ ObjectId("51b610972f52760fcc003331") ] }})
Hopefully this is helpful to others just learning, syntaxs are different in each. I was told that mongo console runs with javascript, where the rails console (and within the project) is using the activerecord to run the call then manipulate the MongoDB. The commenter above was only addressing accessing the mongoDB directly from within a script. So hopefully this is a little more complete in the different ways you could run into this issue.

Related

How can I access columns.roles in Power BI development?

Could not find this answer online, so decided to post the question then the answer.
I created a table in the capabilities.json file:
"dataRoles": [
{
"displayName": "Stakeholders",
"name": "roleIwant",
"kind": "GroupingOrMeasure"
}
...
"dataViewMappings": [
{
"table": {
"rows": {
"select": [
{
"for": {
"in": "roleIwant"
}
}
]
}
}
}
]
I realized that I could not simply set, for instance, legend data from the first category, because the first category comes from the first piece of data the user drags in, regardless of position. So if they set a bunch of different pieces of data in Power BI online, for instance, then remove one, the orders of everything get messed up. I thought the best way to settle this would be to identify the role of each column and go from there.
When you click on show Dataview, the hierarchy clearly shows:
...table->columns[0]->roles: { "roleIwant": true }
So I thought I could access it like:
...table.columns[0].roles.roleIwant
but that is not the case. I was compiling using pbiviz start from the command prompt, which gives me an error:
error TYPESCRIPT /src/visual.ts : (56,50) Property 'roleIwant' does not exist on type '{ [name: string]: boolean; }'.
Why can I not access this in this way? I was thinking because natively, roles does not contain the property roleIwant, which is true, but that shouldn't matter...
The solution is actually pretty simple. I got no 'dot' help (typing a dot after roles for suggestions), but you can use regular object properties for roles. The command for this case would be:
...table.columns[0].roles.hasOwnProperty("roleIwant")
And the functional code portion:
...
columns.forEach((column) =>{
if(column.roles.hasOwnProperty("roleIwant")){
roleIwantData = dataview.categorical.categories[columns.indexOf(column)].values;
})
If it has the property, it belongs to that role. From here, the data saved will contain the actual values of that role! The only thing I would add on here is that if a column is used for multiple roles, depending on how you code, you may want to do multiple if's to check for the different roles belonging to a column instead of if else's.
If anyone has any further advice on the topic, or a better way to do it, by all means. I searched for the error, all over for ways to access columns' roles, and got nothing, so hopefully this topic helps someone else. And sorry for the wordiness - I tend to talk a lot.

Unable to use Ember data with JSONAPI and fragments to support nested JSON data

Overview
I'm using Ember data and have a JSONAPI. Everything works fine until I have a more complex object (let's say an invoice for a generic concept) with an array of items called lineEntries. The line entries are not mapped directly to a table so need to be stored as raw JSON object data. The line entry model also contains default and computed values. I wish to store the list data as a JSON object and then when loaded back from the store that I can manipulate it as normal in Ember as an array of my model.
What I've tried
I've looked at and tried several approaches, the best appear to be (open to suggestions here!):
Fragments
Replace problem models with fragments
I've tried making the line entry model a fragment and then referencing the fragment on the invoice model as a fragmentArray. Line entries add to the array as normal but default values don't work (should they?). It creates the object and I can store it in the backend but when I return it, it fails with either a normalisation issue or a serialiser issue. Can anyone state the format the data be returned in? It's confusing as normalising the data seems to require JSONAPI but the fragment requires JSON serialiser. I've tried several combinations but no luck so far. My line entries don't have actual ids as the data is saved and loaded as a block. Is this an issue?
DS.EmbeddedRecordsMixin
Although not supported in JSONAPI, it sounds possible to use JSONAPI and then switch to JSONSerializer or RESTSerializer for the problem models. If this is possible could someone give me a working example and the JSON format that should be returned by the API? I have header authorisation and other such data so would I still be able to set this at the application level for all request not using my JSONAPI?
Ember-data-save-relationships
I found an add on here that provides an add on to do this. It seems more involved than the other approaches but when I've tried this I can send the data up by setting a the data as embedded. Great! But although it saves it doesn't unwrap it correct and I'm back with the same issues.
Custom serialiser
Replace the models serialiser with something that takes the data and sends it as plain JSON data and then deserialises back into something Ember can use. This sounds similar to the above but I do the heavy lifting. The only reason to do this is because all examples for the above solutions are quite light and don't really show how to set this up with an actual JSONAPI set up that would need it.
Where I am and what I need
Basically all approaches lead to saving the JSON fine but the return JSON from the server not being the correct format or the deserialisation failing but it's unclear what it should be or what needs to change without breaking the existing JSONAPI models that work fine.
If anyone know the format for return API data it may resolve this. I've tried JSONAPI with lineEntries returning the same format as it saved. I've tried placing relationship sections like the add on suggested and I've also tried placing relationship only data against the entries and an include section with all the references. Any help on this would be great as I've learned a lot through this but deadlines a looming and I can't see a viable solution that doesn't break as much as it fixes.
If you are looking for return format for relational data from the API server you need to make sure of the following:
Make sure the relationship is defined in the ember model
Return all successes with a status code of 200
From there you need to make sure you return relational data correctly. If you've set the ember model for the relationship to {async: true} you need only return the id of the relational model - which should also be defined in ember. If you do not set {async: true}, ember expects all relational data to be included.
return data with relationships in JSON API specification
Example:
models\unicorn.js in ember:
import DS from 'ember-data';
export default DS.Model.extend({
user: DS.belongsTo('user', {async: true}),
staticrace: DS.belongsTo('staticrace',{async: true}),
unicornName: DS.attr('string'),
unicornLevel: DS.attr('number'),
experience: DS.attr('number'),
hatchesAt: DS.attr('number'),
isHatched: DS.attr('boolean'),
raceEndsAt: DS.attr('number'),
isRacing: DS.attr('boolean'),
});
in routes\unicorns.js on the api server on GET/:id:
var jsonObject = {
"data": {
"type": "unicorn",
"id": unicorn.dataValues.id,
"attributes": {
"unicorn-name" : unicorn.dataValues.unicornName,
"unicorn-level" : unicorn.dataValues.unicornLevel,
"experience" : unicorn.dataValues.experience,
"hatches-at" : unicorn.dataValues.hatchesAt,
"is-hatched" : unicorn.dataValues.isHatched,
"raceEndsAt" : unicorn.dataValues.raceEndsAt,
"isRacing" : unicorn.dataValues.isRacing
},
"relationships": {
"staticrace": {
"data": {"type": "staticrace", "id" : unicorn.dataValues.staticRaceId}
},
"user":{
"data": {"type": "user", "id" : unicorn.dataValues.userId}
}
}
}
}
res.status(200).json(jsonObject);
In ember, you can call this by chaining model functions. For example when this unicorn goes to race in controllers\unicornracer.js:
raceUnicorn() {
if (this.get('unicornId') === '') {return false}
else {
return this.store.findRecord('unicorn', this.get('unicornId', { backgroundReload: false})).then(unicorn => {
return this.store.findRecord('staticrace', this.get('raceId')).then(staticrace => {
if (unicorn.getProperties('unicornLevel').unicornLevel >= staticrace.getProperties('raceMinimumLevel').raceMinimumLevel) {
unicorn.set('isRacing', true);
unicorn.set('staticrace', staticrace);
unicorn.set('raceEndsAt', Math.floor(Date.now()/1000) + staticrace.get('duration'))
this.set('unicornId', '');
return unicorn.save();
}
else {return false;}
});
});
}
}
The above code sends a PATCH to the api server route unicorns/:id
Final note about GET,POST,DELETE,PATCH:
GET assumes you are getting ALL of the information associated with a model (the example above shows a GET response). This is associated with model.findRecord (GET/:id)(expects one record), model.findAll(GET/)(expects an array of records), model.query(GET/?query=&string=)(expects an array of records), model.queryRecord(GET/?query=&string=)(expects one record)
POST assumes you at least return at least what you POST to the api server from ember , but can also return additional information you created on the apiServer side such as createdAt dates. If the data returned is different from what you used to create the model, it'll update the created model with the returned information. This is associated with model.createRecord(POST/)(expects one record).
DELETE assumes you return the type, and the id of the deleted object, not data or relationships. This is associated with model.deleteRecord(DELETE/:id)(expects one record).
PATCH assumes you return at least what information was changed. If you only change one field, for instance in my unicorn model, the unicornName, it would only PATCH the following:
{
data: {
"type":"unicorn",
"id": req.params.id,
"attributes": {
"unicorn-name" : "This is a new name!"
}
}
}
So it only expects a returned response of at least that, but like POST, you can return other changed items!
I hope this answers your questions about the JSON API adapter. Most of this information was originally gleamed by reading over the specification at http://jsonapi.org/format/ and the ember implementation documentation at https://emberjs.com/api/data/classes/DS.JSONAPIAdapter.html

Is it possible to have an Array of hstore in PostgreSQL

I am a complete beginner in PostgreSQL. And I was really amazed by the hstore datatype provided by Postgres. Well, I am using the Rails 3 framework and developing a simple app that uses PostgreSQL. I want to store an array of hashes in a field.
For Eg.:
authors: [
{
name: "abc",
email: "abc#example.com"
},
{
name: "xyz",
email: "xyz#example.com"
}
]
Is this possible in PostgreSQL using Rails 3? If so, can somebody give insights on how?
Thanks
It's certainly possible to create an array-of-hstore column in Rails 4 with e.g. a column spec like this in the table creation:
t.hstore :properties, :array => true
However, there's an encoding bug in Rails 4.0 that unfortunately renders them unusable; essentially you can read from them and they present correctly as arrays of hashes, but not write.
I've opened an issue (with fix patch) at https://github.com/rails/rails/issues/11135 which hopefully will be incorporated soon.
I'm not sure if they'll allow you to have an hstore array, but there are a few active record extensions that add hstore and array types. e.g.:
https://github.com/funny-falcon/activerecord-postgresql-arrays
https://github.com/engageis/activerecord-postgres-hstore
https://github.com/tlconnor/activerecord-postgres-array
Don't miss the Rails 4-related improvements, too:
http://blog.remarkablelabs.com/2012/12/a-love-affair-with-postgresql-rails-4-countdown-to-2013

Asana: Adding a task to a project when you create it

I am trying to use the Asana API to create a task that is assigned to me and added to an existing project.
I have tried by not specifying the workspace as suggested by someone else but the task creation still fails.
The jSon I am using is the following;
{ "data":
{
"name":"Testing Project",
"followers":[10112, 141516],
"workspace":6789,
"assignee":12345,
"project": 1234
}
}
If I create the task and then send another call to the API with the following jSon it works, but this means I need to make 2 API calls every time I create a task.
{
"project": 1234
}
Rather old question but it might help someone. Yes, you can attach a task to a project during creation using the 'projects' (not 'project' as stated above) param, passing its id.
You can also attach the task to many projects stating an array at 'projects' => {22, 33, 44}.
It's all here at https://asana.com/developers/api-reference/tasks
(I work for Asana)
The specification for Tasks can be found here: https://asana.com/developers/api-reference/tasks
Notably, you cannot specify a project during creation - you must go through the addProject call for each project you wish to add.
If there is contradictory information on another SO question, I apologize as that may have been written without first double-checking the implementation.
The actual problem is that you are passing an int instead of an string for "projects". Some attributes work well as string or int (e.g. "assignee" or "workspace") but not "projects".
..so correct your json to the following:
{
"data":
{
"name":"Testing Project",
"followers":[10112, 141516],
"workspace":6789,
"assignee":12345,
"project": "1234"
}
}
I wasted half a day -.-'

Problem with RavenDB 'Hello World' tutorial

I am going through the RavenDB tutorial on the RavenDb.net website.
It was going fine until I got to the code block for creating an index.
This code segment is direct from RavenDB.Net website.
store.DatabaseCommands.PutIndex("OrdersContainingProduct", new IndexDefinition<Order>
{
Map = orders => from order in orders
from line in order.OrderLines
select new { line.ProductId }
});
I get an error on compile: "The non-generic type 'Raven.Database.Indexing.IndexDefinition' cannot be used with type arguments."
If IndexDefinition is non-generic, why is it used as generic in the sample code? Where is the disconnect?
Thank you for your time
Jim
Depending on your using statements you may be referencing the wrong IndexDefinition class (from another Raven assembly). Try adding this to the beginning of your file:
using Raven.Client.Indexes;
You might need to remove other using statements as well. I guess this is one reason why Microsoft recommends using unique names for classes even in the presence of namespaces.