Backbone.js why a model from a collection doesn't have url set? - ruby-on-rails

I am still relatively new to Backbone. I'm just beginning to get a sense of how it works. I 've been using Rails for a while and it's what is giving me some hint at times of using Backbone. so here goes:
Simple, I have a Company model over in Rails say I do in javascript console
companies = new Backbone.Collection();
companies.url = '/companies';
companies.url; // '/companies'
companies.fetch();
company = companies.at(0);
company.url
The last line, "company.url" doens't return what I expect, what I expect is something like '/companies/12345' so that when I update company and decide to save it, it will know where to "put" to.
So does that mean that everytime I want something saved, I have to save on the whole collection?(!)

I would take a look at what company.url() is returning. Saving the whole collection should not be necessary.

I was trying your problem, and found that the models are not getting an id to it. So the url method on the models is not working. So i think you need to put your collections like below (what i tried)
cltn = Backbone.Collection.extend({
model:modelName,
parse:function(res){
var i = 0;
var itms = _.map(res.items, function(o){
o.id = ++i;
return o
})
return itms;
}
});
cltnInst = new cltn();
cltnInst.url="/combodata.json?";
cltnInst.fetch();
Then in your firebug type the below codes.
cltnInst.url; // this is a string props. output will be "/combodata.json?"
cltnInst.at(0).url() // this is a method props output will be "/combodata.json?/1"
combodata.json will be of this format
{
"identifier": "title",
"items": [
{
"title": "A",
"tag": "htmlcss",
"date": "today"
}, ...
]}
Please correct me if my answer is wrong.

I have actually made a mistake in the step where I make an attempt to create a new companies collection.
So instead of
var Companies = new Backbone.Collection()
I should really do something like this:
var Companies = Backbone.Collection.extend({
model: Company,
url : '/companies'
});
var Company = Backbone.Model.extend();
var companies_collection = new Companies()
companies_collection.fetch()
companies_collection.models[0].url() // '/projects/123'

Related

Querying Relationships in Laravel 5.2

I am having issues trying to query an Eloquent relationship.
I have 2 tables
tbl_deals
id
deal_id
merchant_id
tbl_merchants
id
merchant_id
merchant_url_text
I defined a deal model as
class deal extends Model
{
public function merchant() {
return $this->hasOne('App\merchant', 'merchant_id', 'merchant_id');
}
}
Now, I want to query all deals based where merchant_url_text = a variable in my controller
Here's what I am trying
$deals = deal::with('merchant')->get(); //Retrieving all the deals with merchants
If I return $deals its giving me all deals with merchant relationship.
How do I constraint the deals by saying where merchant_url_text = $variable
I am trying
return $deals->where('merchant_url_text', $merchant_url_text)->get();
but it is giving me an error saying :
"Missing argument 1 for Illuminate\Support\Collection::get(), called in ..."
I tried to lookup the documentation for querying relationships in Laravel Docs. It talks about this example
$user = App\User::find(1);
$user->posts()->where('active', 1)->get();
In this case, its trying to get the first user and finding corresponding posts related to the user.
In my case I want to filter from all deals, the deals that have merchant_url_text = a specific variable in my controller.
Any help on how I can achieve this?
Thanks
Try the following code :
$specific_merchant_url_text = "i don't know";
$deals_with_specific_merchant_url_text = [];
$deals = deal::with('merchant')->get();
foreach($deals as $deal)
if( $deal->merchant->merchant_url_text==$specific_merchant_url_text)
array_push($deals_with_specific_merchant_url_text, $deal);
So you get array of deals with specific merchant url text in deals_with_specific_merchant_url_text.
Another approach using DB object :
$deals = DB::table('deals')
->join('merchants', 'deals.merchant_id', '=', 'merchants.id')
->select('deals.*')
->where('merchants.merchant_url_text', $merchant_url_text)
->get();
Yours with raw :
$deals = deal::selectRaw('tbl_deals.*')
->Join('merchants','deals.merchant_id','=','merchants.merchant_id')
->where('merchants.merchant_url_text', '=', $merchant_url_text) ->get();
Hope this helps.
With takes a callback. This will bring back all deals but only eager load merchants that match.
$deals = Deal::with(['merchant' => function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
}])->get();
Flip-side: if you only want deals with a matching merchant, use where has.
$deals = Deal::whereHas('merchant', function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
})->get();
If you want both, chain them:
$deals = Deal::whereHas('merchant', function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
})->with(['merchant' => function ($query) use ($url_text){
return $query->where('merchant_url_text', $url_text);
}])->get();
I capitalized deal because it's standard. It wasn't capitalized in your example.
You can use query builder join query .
DB::table('tbl_merchants')
->join('tbl_deals', 'tbl_merchants.merchant_id', '=','tbl_deals.merchant_id')
->where('tbl_merchants.merchant_url_text',$merchant_url_text)
->get();

Update field of embedded documents on multiple Mongoid documents [duplicate]

This question already has answers here:
How to Update Multiple Array Elements in mongodb
(16 answers)
Closed 5 years ago.
I recently started using MongoDB and I have a question regarding updating arrays in a document.
I got structure like this:
{
"_id" : ObjectId(),
"post" : "",
"comments" : [
{
"user" : "test",
"avatar" : "/static/avatars/asd.jpg",
"text" : "....."
}
{
"user" : "test",
"avatar" : "/static/avatars/asd.jpg",
"text" : "....."
}
{
"user" : "test",
"avatar" : "/static/avatars/asd.jpg",
"text" : "....."
}
...
]
}
I'm trying to execute the following query:
update({"comments.user":"test"},{$set:{"comments.$.avatar": "new_avatar.jpg"}},false,true)
The problem is that it update all documents, but it update only the first array element in every document. Is there any way to update all array elements or I should try to do it manually?
Thanks.
You cannot modify multiple array elements in a single update operation. Thus, you'll have to repeat the update in order to migrate documents which need multiple array elements to be modified. You can do this by iterating through each document in the collection, repeatedly applying an update with $elemMatch until the document has all of its relevant comments replaced, e.g.:
db.collection.find().forEach( function(doc) {
do {
db.collection.update({_id: doc._id,
comments:{$elemMatch:{user:"test",
avatar:{$ne:"new_avatar.jpg"}}}},
{$set:{"comments.$.avatar":"new_avatar.jpg"}});
} while (db.getPrevError().n != 0);
})
Note that if efficiency of this operation is a requirement for your application, you should normalize your schema such that the location of the user's avatar is stored in a single document, rather than in every comment.
One solution could be creating a function to be used with a forEach and evaling it (so it runs quickly). Assuming your collection is "article", you could run the following:
var runUpdate = function(){
db.article.find({"comments.user":"test").forEach( function(article) {
for(var i in article.comments){
article.comments[i].avatar = 'new_avatar.jpg';
}
db.article.save(article);
});
};
db.eval(runUpdate);
If you know the indexes you want to update you can do this with no problems like this:
var update = { $set: {} };
for (var i = 0; i < indexesToUpdate.length; ++i) {
update.$set[`comments.${indexesToUpdate[i]}. avatar`] = "new_avatar.jpg";
}
Comments.update({ "comments.user":"test" }, update, function(error) {
// ...
});
be aware that must of the IDE's will not accept the syntax but you can ignore it.
It seems like you can do this:
db.yourCollection.update({"comments.user":"test"},{$set:{"comments.0.avatar": "new_avatar.jpg", "comments.1.avatar": "new_avatar.jpg", etc...})
So if you have a small known number of array elements, this might be a little easier to do. If you want something like "comments.*.avatar" - not sure how to do that. It is probably not that good that you have so much data duplication tho..

SAPUI5 - complex model binding

I have this json model:
model/data.json
{
"orders" : [
{
"header" : { "id" : "00001", "description" : "This is the first order" },
"items" : [
{ "name" : "Red Book","id" : "XXYYZZ" },
{ "name" : "Yellow Book", "id" : "AACCXX" },
{ "name" : "Black Book", "id" : "UUEEAA" },
]
},
{
// another order with header + items
},
.....
]
}
and I'm assigning it onInit to the view, like this:
var model = new sap.ui.model.json.JSONModel("model/data.json");
sap.ui.getCore().setModel(reqModel);
I'm trying to display a list of orders in the first view (showing the id), like this:
var list = new sap.m.List({
id: "mainList",
items: []
});
var items = new sap.m.ActionListItem({
text : "{id}",
press : [ //click handler, onclick load the order details page ]
});
list.bindItems("/orders", items);
.... // add list to the page etc etc
What I cannot do, is connect each order to its header->id.. I tried
text: "/header/{id}"
text: "{/header/id}"
in the items declaration, and
list.bindItems("/orders/header", items)
in the list binding, but none of them works.. The id value is not displayed, even though a "blank" list item is shown..
Any idea? What am I doing wrong?
Thank you
The solution was one of those I tried (but I don't know why it didn't work at that time)
text: "{/header/id}"
The ListItem acts as a Template for a list/array of objects. That's why you bind it against an array structure in your data:
list.bindItems("/orders", itemTemplate)
That makes bindings of the ListItem relative to /orders and therefore your item should look like this without leading '/' (absolute paths would look like this /orders/0/header/id asf.):
var itemTemplate = new sap.m.ActionListItem({
text : "{header/id}",
press : [ //click handler, onclick load the order details page ]
});
Not quite sure how you made it work the way you have shown... May be it's not as picky as I thought.
Btw: For whatever reason the ResourceModel builds an exception of that syntax. You can always omit the leading '/' when dealing with ResourceModels (probably because they do not allow nested structures).
BR
Chris
Cannot add comments yet, therefore an answer to you solved Problem, that could answer the initial problem. (And inform People using that example in any way)
In the current code listing you use the variable "reqModel" to set the model, but the variable with the model in it is named "model" in the line before. Maybe that was the first reason why both of your examles would not work?
Perhaps this error was cleared on rewriting some passages while testing.
greetings! -nx

Getting data back on Html.ListBoxFor post in MVC

It seems all the examples I can find use a ViewModel for some reason, so a MVC and not MVVM answer is what I'm looking for :)
Controller
List<PermOptions> have = new List<PermOptions>();
List<PermOptions> nothave = new List<PermOptions>();
...populate the lists here...
var set = new PermissionSet
{
ExtId = extid,
HaveList = have,
NotHaveList = nothave
};
return View(set);
View
#model path.to.model.PermissionSet
#{
var NotHave = new MultiSelectList(Model.NotHaveList, "Id", "Role");
}
#Html.ListBoxFor(model => model.NotHaveList, NotHave, new { #size = "30", id = "possible" });
#{
var Have = new MultiSelectList(#Model.HaveList, "Id", "Role");
}
#Html.ListBoxFor(model => model.HaveList, Have, new { #size = "30", id = "have" });
Everything works just fine displaying the initial lists and moving items, but when I submit the form the ListBoxFors are part of to the Post action, PermissionSet.HaveList and PermissionSet.NotHaveList are empty with a zero count. Thinking it was a select issue or format of return issue, I added javascript to select all the items in both boxes, and in the browser debug pane I can see that there are values in the submitted Form data that match up to various option values for NotHave and Have, but if in the Post action, I make a call to ViewData["NotHave"], it is also reporting empty.
What do I need to do to get the list of items in each ListBoxFor in my Post controller, preferrably as part of PermissionSet?

How can I get a specific Neo4j node using Neo4jClient

Some pseudo-code of the model I'm working with:
User { int Id, string Username }
Activity { int Id, string Name }
Place { int Id, string Name }
Basically I have a bunch of Users and they belong to certain places (many to many relationship in RDBMS world). What I'd like to do now that I've created all of the nodes already is create the relationship between them. To do that I believe I need to get references to each node and then simply create the relationship between them.
Note: So far no relationships exist. It does look like in some of the examples they have added the User nodes with a relationship that points to the RootNode but I have no idea why. I'm not sure if I need to do that or not.
More pseudo-code:
var userRef = _graphClient...GetUserNodeWhereIdEquals(user.Id);
// or something like _graphClient.OutV<User>("[[id={0}]]", user.Id)
// or even just _graphClient.V<User>(id == user.Id)
var placeRef = _graphClient...GetPlaceNodeWhereIdEquals(place.Id);
_graphClient...CreateRelationshipBetween(userRef, placeRef, "belongs_to");
Unfortunately the documentation starts off pretty great then goes south when you get to relationships.
Update 3/29/12
Here's the code I have so far:
foreach (var a in _activityTasks.GetAll())
{
_graphClient.Create(a, new ActivityBelongsTo(_graphClient.RootNode));
}
foreach (var p in _placeTasks.GetAll().Take(1))
{
var placeNode = _graphClient.Create(p, new PlaceBelongsTo(_graphClient.RootNode));
foreach (var activity in p.Activities)
{
Activity activity1 = activity;
var activityNode = _graphClient.RootNode.In<Activity>(ActivityBelongsTo.TypeKey, a => a.Id == activity1.Id).SingleOrDefault();
_graphClient.CreateRelationship(placeNode, new PlaceHasActivity(activityNode.Reference));
}
}
The activity nodes are created fine. The place node is created fine. An error is now being thrown when trying to get the activityNode. It's a rather large stack trace so I'll try to paraphrase here:
Received an exception when executing the request.
The query was: g.v(p0).in(p1).filter{ it[p2] == p3
}.drop(p4).take(p5)._()
The exception was: Value cannot be null. Parameter name: key
System.ArgumentNullException: Value cannot be null.Parameter name: key
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue
value, Boolean add) ... The raw response body was: [ {
"outgoing_relationships" :
"http://localhost:7474/db/data/node/2/relationships/out", "data" : {
"Name" : "Aerobics", "Id" : 2 }, "all_typed_relationships" :
"http://localhost:7474/db/data/node/2/relationships/all/{-list|&|types}",
"traverse" :
"http://localhost:7474/db/data/node/2/traverse/{returnType}", "self"
: "http://localhost:7474/db/data/node/2", "property" :
"http://localhost:7474/db/data/node/2/properties/{key}",
"outgoing_typed_relationships" :
"http://localhost:7474/db/data/node/2/relationships/out/{-list|&|types}",
"properties" : "http://localhost:7474/db/data/node/2/properties",
"incoming_relationships" :
"http://localhost:7474/db/data/node/2/relationships/in", "extensions"
: { }, "create_relationship" :
"http://localhost:7474/db/data/node/2/relationships",
"paged_traverse" :
"http://localhost:7474/db/data/node/2/paged/traverse/{returnType}{?pageSize,leaseTime}",
"all_relationships" :
"http://localhost:7474/db/data/node/2/relationships/all",
"incoming_typed_relationships" :
"http://localhost:7474/db/data/node/2/relationships/in/{-list|&|types}"
} ]
Something to do when adding a item to a Dictionary when the key is null. Problem is, I don't see any nulls when I debug on my end, activity1 is there, RootNode is there, TypeKey is a const string.
I'm almost wondering if I should just keep the created nodes within a array or Dictionary myself and then just working with the NodeReference. That's what I'm going to try next.
Later that morning
This seems to load everything into the graph database fine:
var activityNodes = _activityTasks.GetAll().ToDictionary(a => a.Id, a => _graphClient.Create(a, new ActivityBelongsTo(_graphClient.RootNode)));
foreach (var p in _placeTasks.GetAll())
{
var placeNode = _graphClient.Create(p, new PlaceBelongsTo(_graphClient.RootNode));
foreach (var activity in p.Activities)
{
_graphClient.CreateRelationship(placeNode, new PlaceHasActivity(activityNodes[activity.Id]));
}
}
foreach (var u in _userTasks.GetAllUserGraph())
{
var userNode = _graphClient.Create(u, new UserBelongsTo(_graphClient.RootNode));
foreach(var activity in u.Activities)
{
_graphClient.CreateRelationship(userNode, new UserParticipatesIn(activityNodes[activity.Id]));
}
}
Now the problem is similar to what I had before. Now I want to get an activity that has a relationship to the RootNode:
Node<Activity> activity = _graphClient
.RootNode
.In<Activity>(ActivityBelongsTo.TypeKey, a => a.Id == 1)
.SingleOrDefault();
Throwing the key value can't be null exception again. I think I need to investigate the gremlin syntax more. I'm guessing the problem is there.
This afternoon
Started to experiment with Gremlin queries:
g.v(0).inE.filter{it.label=="ACTIVITY_BELONGS_TO"}.outV.filter{it.Id==1}.Name
works fine. I tried to replicate that using neo4jClient syntax:
_graphClient.RootNode.InE(ActivityBelongsTo.TypeKey).OutV(b => b.Id == 1).SingleOrDefault();
Same null exception, it spits out:
g.v(p0).inE.filter{ it[p1].equals(p2) }.outV.filter{ it[p3] == p4 }.drop(p5).take(p6)._()
which looks right to me, except for the end. Ran this though:
g.v(0).inE.filter{it.label=="ACTIVITY_BELONGS_TO"}.outV.filter{it.Id==1}.drop(0).take(1)._()
And that works fine. Something stinks here...maybe I should try the other library although I liked the de/serialization support. Sigh...
Thought maybe a raw query would work. Nope! This method no longer accepts a string and the required GremlinQuery I have no idea how to you. Grooooooooooooooooan.
var users = graphClient.ExecuteGetAllNodesGremlin<IsCustomer>("g.v(0).out('IsCustomer'){it.'Name' == 'BobTheBuilder'}");
Update 3/30/12
Created a new project, everything below works fine. Super confused why it will work here... :( Maybe version differences, I have no idea.
var client = new GraphClient(new Uri("http://localhost:7474/db/data"));
client.Connect();
client.Create(new User { Id = 1, Username = "joe" }, new UserBelongsTo(client.RootNode));
client.Create(new User { Id = 2, Username = "cloe" }, new UserBelongsTo(client.RootNode));
client.Create(new Activity { Id = 1, Name = "Bocce Ball" }, new ActivityBelongsTo(client.RootNode));
client.Create(new Activity { Id = 2, Name = "Programming" }, new ActivityBelongsTo(client.RootNode));
var user = client.RootNode.In<User>(UserBelongsTo.TypeKey, u=>u.Id == 1).SingleOrDefault();
var activity = client.RootNode.In<Activity>(ActivityBelongsTo.TypeKey, a=>a.Id == 1).SingleOrDefault();
client.CreateRelationship(user.Reference, new Plays(activity.Reference));
user = client.RootNode.In<User>(UserBelongsTo.TypeKey, u => u.Id == 1).SingleOrDefault();
activity = client.RootNode.In<Activity>(ActivityBelongsTo.TypeKey, a => a.Id == 1).SingleOrDefault();
I'm just getting started too. I would suggest you check out this blog:
http://romikoderbynew.com/2011/07/30/neo4jclient-primer/
Also, check http://frictionfree.org and its source code (in the about section) for more examples.
Creating relationships on existing - as I understand, this is possible. However, it appears to be easier to associate nodes as you create them. From the blog:
You can also create relationships between existing nodes.
graphClient.CreateRelationship(customerNodeReference, new
Speaks(languageNode.Reference));
RootNode - I believe you need to start a query from a node, I don't think you can do a
SELECT * FROM ... WHERE
Therefore, it would make sense that you need to attach nodes to the root node. This is an example from the FrictionFreeApp:
var node = graphClient.Create(
user,
new UserBelongsTo(rootNode));

Resources