Many-To-Many Association on Same Model using Waterline & Sails.js [duplicate] - orm

I'm pretty new on Nodejs and sails.
I'm implementing a server which is similiar to Twitter. In user model, there should be 2 fields: follower and following, and the 2 fields are association of the model 'user' itself.
My question is when the model have only 1 association, either follower or following, it works.
However, when both follower and following included, there would be en error.
The code is something like this:
module.exports = {
attributes: {
alias: {
type:'string',
required: true,
primaryKey: true
},
pwd: {
type: 'string',
required: true
},
follower: {
collection: 'user',
via: 'alias'
},
following:{
collection: 'user',
via: 'alias'
}
}
The code will cause such error:
usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/references.js:115
throw new Error('Trying to associate a collection attribute to a model tha
^
Error: Trying to associate a collection attribute to a model that doesn't have a Foreign Key. user is trying to reference a foreign key in user
at References.findReference (/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/references.js:115:11)
at References.addKeys (/usr/local/lib/node_modules/sails/node_modules/waterline/node_modules/waterline-schema/lib/waterline-schema/references.js:72:22)

For such usage your model definition is incorrect, namely the via keywords. As per the waterline associations docs the via keyword references the other side of the association. So, for a follower the other side is following and vice-versa. In other words:
follower: {
collection: 'user',
via: 'following'
},
following:{
collection: 'user',
via: 'follower'
}
You can check a full working example at: https://github.com/appscot/sails-orientdb/blob/master/test/integration-orientdb/tests/associations/manyToMany.selfReferencing.js

Related

API Platform - Get collection where Author is User

I currently have an Offer entity which has an author property, like so :
#[ORM\ManyToOne(targetEntity: User::class, inversedBy: 'offers')]
#[ORM\JoinColumn(nullable: false)]
private $author;
Currently, when I do a get request on /offers/, I get a collection of ALL the offers, which is normal.
I would want to only retrieve the offers where the author is the logged in user instead. (basically a findBy(['author'=>$this->getUser()]))
After searching on the internet I've been trying the following, which obviously is not working
#[ORM\Entity(repositoryClass: OfferRepository::class)]
#[ApiResource(
normalizationContext: [
'groups' => ['read'],
],
itemOperations: [
'get' => [
'security' => 'object.author == user',
]
],
collectionOperations: [
'get' => [
'security' => 'object.author == user',
]
]
)]
class Offer
{
...
This gives me the following error :
hydra:description: "Warning: Undefined property:
ApiPlatform\Core\Bridge\Doctrine\Orm\Paginator::$author"
Which tells me this is completely the wrong approach.
Kind of stuck here, any hint ?
Thank you.
Maybe a bit late but this is answered by implementing an "extension". That would allow the collection to be filtered to match only items with a specific condition (in your case, a User).
There's an old issue (here: https://github.com/api-platform/core/issues/1481).
And official documentation here: https://api-platform.com/docs/core/extensions/#example.

Open API schema conditional response field based on the presence of a query parameter

I am working on providing a GET REST API where I would like to conditionally include the total_documents field (its an integer count of the total number of records present in the DB table).
The API signature and response payload will be something like:
GET /endpoint/?total_documents&.....
Response Payload:
{
documents: [....],
total_documents: 100
}
Now I would like the total_documents field to be appeared in the response payload if and only if the total_documents query parameter exists in the URL.
This is what I tried, based on my schema:
fastify.addSchema({
$id: 'persistence-query-params',
title: "PersistenceQueryParams",
type: 'object',
description: 'Persistence Service GET API URL query specification. Applicable for GET API only.',
properties: {
'total_documents': {
description: 'Total number of documents present in the collection, after applying filters, if any. This query paramater does not take any value, just pass it as the name (e.g. &total_documents).',
nullable: true,
},
},
}
querystring: {
description: 'Persistence Service GET API URL query specification. Applicable for GET API only.',
$ref: 'persistence-query-params#',
},
response: {
200: {
properties: {
'documents': {
description: 'All the retrieved document(s) from the specified collection for the specified service database and account.',
type: 'array',
items: {
$ref: 'persistence-response-doc#',
}
},
'total_documents': {
description: "If total_documents query paremeter is specified, gives the total number of documents present in the collection, after applying query paramaters, if any. If total_documents is not specified, this field will not be available in the response payload.",
type: 'number',
default: -1,
},
},
dependencies: {
'total_documents': { required: ['querystring/properties/total_documents'] },
},
},
'4xx': {
$ref: 'error-response#',
description: 'Error response.'
}
}
What is the way out here?
Thanks,
Pradip
JSON Schema has no notion of a request or response or HTTP.
What you have here is an OpenAPI specification document.
The OpenAPI specification defines a way to access dynamic values, but only within Link Objects or Callback Objects, which includes the query params.
Runtime expressions allow defining values based on information that
will only be available within the HTTP message in an actual API call.
This mechanism is used by Link Objects and Callback Objects.
https://spec.openapis.org/oas/v3.1.0#runtime-expressions
JSON Schem has no way to reference instance data, let alone data relating to contexts it is unaware of.

Can I POST multiple patch requests to RavenDB's /bulk_docs HTTP API endpoint?

I'm in the process of writing a node wrapper for RavenDB.
I'm using version 3 but as there are no HTTP docs for it, I've been relying on the 2.0 and 2.5 docs.
In regards to single document operations, I've used this doc page successfully for PUTs, DELETEs and multiple PATCHs to individual documents.
Similarly, I've used this doc page successfully for multiple PUTs and DELETEs of several documents in one HTTP call but the docs are a bit vague in regards to PATCHing mutliple documents in one call.
Under the "Batching Requests" heading, it clearly states it's possible:
Request batching in RavenDB is handled using the '/bulk_docs' endpoint, which accepts an array of operations to execute. The format for the operations is:
method - PUT, PATCH or DELETE.
...
For PUTs, I POST to /bulk_docs:
[
{
Method: 'PUT',
Key: 'users/1',
Document: { username: 'dummy' }
Metadata: { 'Raven-Entity-Type': 'Users' }
},
...
]
For DELETEs, I POST to /bulk_docs:
[
{
Method: 'DELETE',
Key: 'users/1'
},
...
]
For PATCHs, I've tried POSTing the following without any luck:
[
{
Method: 'PATCH',
Key: 'users/1',
Document: {
Type: 'Set',
Name:'username',
Value: 'new-username'
}
},
...
]
and
[
{
Method: 'PATCH',
Key: 'users/1',
Type: 'Set',
Name:'username',
Value: 'new-username'
},
...
]
All I'm getting back is 500 - Internal Server Error and without any examples of PATCHing multiple documents on that docs page I'm kind of stuck...
Any help would be appreciated :)
The structure for PATCH is :
[
{
Method: 'PATCH',
Key: 'users/1',
Patches: [{
Type: 'Set',
Name:'username',
Value: 'new-username'
}]
},
...
]
The full structure can be see here:
https://github.com/ayende/ravendb/blob/master/Raven.Abstractions/Commands/PatchCommandData.cs#L72

No result when Rally.data.WsapiDataStore lacks permissions

I'm calling Ext.create('Rally.data.WsapiDataStore', params), and looking for results with the load event.
I'm requesting a number of objects across programs that the user may or may not have read permission for.
This works fine for queries where the user has permissions. But in the case where the user does not have permission and presumably gets zero results back, the load event does not seem to fire at all. I would expect it to fire with the unsuccessful flag or else to return with empty results.
Since I don't know that the request has failed, my program waits and waits. How can I tell if a this request fails to return because of security?
BTW, looking at the network stats, I believe all my requests get a "200 OK" status back.
Here is the method I use to create the various data stores:
_createDataStore: function(params) {
this.openRequests++;
var createParams = {
model: params.type,
autoLoad: true,
// So I can later determine which query type it is, and which program
requestType: params.requestType == undefined ? params.type : params.requestType,
program: this.program,
listeners: {
load: this._onDataLoaded,
scope: this
},
filters: params.filters,
pageSize: params.pageSize,
fetch: params.fetch,
context: {
project: this.project,
projectScopeUp: false,
projectScopeDown: true
},
pageSize: 1 // We only need the count
};
console.log('_createDataStore', this.program, createParams.requestType);
Ext.create('Rally.data.WsapiDataStore', createParams);
},
And here is the _onDataLoaded method:
_onDataLoaded: function(store, data, successB) {
console.log('_onDataLoaded', this.program, successB);
...
I only see this function called for those queries for which the account has permissions.
Are you getting any request for Defect.js or HierarchicalRequirement.js? When I simulate the issue you are seeing the request for TypeDefinition.js fails when it is building the model because the user doesn't have access to the specified project. This seems like a little bug to me. You should be able to work around it by explicitly fetching the model for a type for a specified workspace and then using that in your store.
Rally.data.ModelFactory.getModels({
types: ['Defect', 'UserStory'], //more types, etc...
context: Rally.environment.getContext().getDataContext(), //use workspace
success: function(models) {
//your code here
}
});

extjs4 rails 3 model validation for uniqueness

i m working with extjs 4 & rails 3.
I want to have validation for uniqueness of field that is on extjs form.
I want to have validation on Rails model for uniqueness, so i have done follwing on my rails model :
validates_uniqueness_of :search_key, :message => "Duplicate value found"
I am inserting new values of form into store as follows :
store.add(values);
If validation fails, the record does not get inserted into database.
Now I want to pop an alert box indicating that the entry is duplicate when validation fails, so that user can edit field.
How can i make this communication betwn rails controller & extjs form for validation?
Also would rails callback will be useful in it?
Here is how to pass messages returned from server to extjs app, I assume you can modify this to suit your need, or let me know if I need to clarify anything:
Extjs
in model, add:
proxy: {
type: 'rest',
url: '/manifest-items',
reader: {
type: 'json', // We expect the server to give us a JSON string as a response
root: 'rows',
totalProperty: 'total',
messageProperty: 'message',
}
},
Rails Controller
Then, in both cases of error or success, returned response should be:
render :json => {:success => false, :message => "some error", :rows => [something], :total => x}.to_json
Back to Extjs
In extjs, the message can be accessed as follows:
important: note the difference between getting error message in failure and success cases.
manifestItem.save({
success: function(records, operation) {
Ext.Msg.alert(operation.resultSet.message);
},
failure: function(records, operation) {
Ext.Msg.alert(operation.error);
}
});