Ember-data check if model was found in store when deserializing through router - ruby-on-rails-3

I have an object route in the router (using ember-data with standard REST backend) with connectOutlets that simply deserializes and loads the object and plugs it into the outlet.
# inside router
action: Ember.Route.extend
route: 'object/:object_id'
connectOutlets: (router, object) ->
unless object.get('isLoaded') # What goes here to tell if the object wasn't found?
#
# handle this case (e.g., redirect)
#
else # otherwise proceed as normal
router.get('applicationController').connectOutlet('object', object)
When I navigate to localhost/#object/object_that_doesnt_exist, the router deserializes the url, attempts to load the object (server logs show a HTTP GET request for localhost/objects/object_that_doesnt_exist), gets a 404, and instead creates a new object with id set to object_that_doesnt_exist.
I want to detect this and handle the case. Right now, I am checking the isLoaded property, which does differentiate between existing models and nonexisting models, but I'm not sure this is the best way.
Ideally, there would be a method similar to Rails' new_record?.

Have a look at the source code: https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/model/model.js#L15
isError: retrieveFromCurrentState,
isNew: retrieveFromCurrentState,
isValid: retrieveFromCurrentState,
Haven't tried myself but isNew might be what you are looking for.

You don't want to do this in connectOutlet because it will require the application to wait while it checks the DB for the record.
Personally I would use a custom find method in my adapter and handle the 404 error from there.
find: function(store, type, id) {
var root = this.rootForType(type);
this.ajax(this.buildURL(root, id), "GET", {
success: function(json) {
this.didFindRecord(store, type, json, id);
},
statusCode: {
404: function() {
# I can never remember the exact semantics, but I think it's something like this
this.trigger('didNotFindRecord');
}
}
})
}
connectOutlets: (router, object) ->
router.get('store').addObserver('didNotFindRecord', this, 'handle404')
router.get('applicationController').connectOutlet('object', object)
handle404: ->
#
# handle this case (e.g., redirect)
#
You will have to be careful to tear down the observers correctly though.

Related

How to show input and output exemple with nelmio-api-bundle and php8.1

I'm currently trying to make an API doc page thanks to nelmio-api-bundle. I only have one route which is a POST route. I'm receiving a JSON in the body of the request and I'm using the Serializer from symfony to deserialize it in a DTO. I'm also using a DTO for the response (which contains the status code, a bool set to true or false, and a message). Now I'm trying to use these DTO (for input and output) to build the API documentation with nelmio-api-bundle but how to make it ? I'm using PHP8.1 attributes to make it, for response it almost works (except that the response is shows as an array) but I don't know how to make it for the inputs.
Here is my current code:
#[Route('/user', methods: ['POST'])]
#[OA\Parameter(
name: 'user',
description: 'The user information in JSON',
in: 'query',
required: true
)]
#[OA\Response(
response: 200,
description: 'Returns the success response',
content: new OA\JsonContent(
type: 'array',
items: new OA\Items(ref: new Model(type: SuccessResponseDTO::class))
)
)]
public function registerUser(Request $request, LoggerInterface $logger): JsonResponse
{
//the code to register the user
}
And here is the result:
Do someone know how to make it ?

Ember Fastboot redirect to external URL

I'm looking to 301 redirect to an external URL from within an Ember Route in Fastboot (based on the data returned by model()).
A solution, would be to access Express.js response object from within Ember, so I can call something like:
res.redirect(301, 'http://external-domain.com')?
However, I'm not entirely sure how res object can be accessed from within Ember.
Fastboot exposes a response object, but it's not the same as the Express res.
The following code will redirect both in Fastboot and in the browser:
if (this.get('fastboot.isFastBoot')) {
this.get('fastboot.response.headers').set('location', 'http://google.com');
this.set('fastboot.response.statusCode', 302);
} else {
window.location.replaceWith('http://google.com');
}

Control cloudflare origin server using workers

I'm trying to use a cloudflare worker to dynamically set the origin based on the requesting IP (so we can serve a testing version of the website internally)
I have this
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
if (request.headers.get("cf-connecting-ip") == '185.X.X.X')
{
console.log('internal request change origin');
}
const response = await fetch(request)
console.log('Got response', response)
return response
}
I'm not sure what to set. The request object doesn't seem to have any suitable parameters to change.
Thanks
Normally, you should change the request's URL, like this:
// Parse the URL.
let url = new URL(request.url)
// Change the hostname.
url.hostname = "test-server.example.com"
// Construct a new request with the new URL
// and all other properties the same.
request = new Request(url, request)
Note that this will affect the Host header seen by the origin (it'll be test-server.example.com). Sometimes people want the Host header to remain the same. Cloudflare offers a non-standard extension to accomplish that:
// Tell Cloudflare to connect to `test-server.example.com`
// instead of the hostname specified in the URL.
request = new Request(request,
{cf: {resolveOverride: "test-server.example.com"}})
Note that for this to be allowed, test-server.example.com must be a hostname within your domain. However, you can of course configure that host to be a CNAME.
The resolveOverride feature is documented here: https://developers.cloudflare.com/workers/reference/apis/request/#the-cf-object
(The docs claim it is an "Enterprise only" feature, but this seems to be an error in the docs. Anyone can use this feature. I've filed a ticket to fix that...)

What's the easiest way to display content depending on the URL parameter value in DocPad

I'd like to check for an URL parameter and then display the confirmation message depending on it.
E.g. if I a GET request is made to /form?c=thankyou docpad shows the form with thank you message
I think there is two basic ways to do this.
look at the url on the server side (routing) and display differing content according to URL parameters
Look at the parameter on the client side using JavaScript and either inject or show a dom element (eg div) that acts as a message box.
To do this on the server side you would need to intercept incoming requests in the docpad.coffee file in the serverExtend event. Something like this:
events:
# Server Extend
# Used to add our own custom routes to the server before the docpad routes are added
serverExtend: (opts) ->
# Extract the server from the options
{server} = opts
docpad = #docpad
# As we are now running in an event,
# ensure we are using the latest copy of the docpad configuraiton
# and fetch our urls from it
latestConfig = docpad.getConfig()
oldUrls = latestConfig.templateData.site.oldUrls or []
newUrl = latestConfig.templateData.site.url
server.get "/form?c=thankyou", (req,res,next) ->
document = docpad.getCollection('documents').findOne({relativeOutPath: 'index.html'});
docpad.serveDocument({
document: document,
req: req,
res: res,
next: next,
statusCode: 200
});
Similar to an answer I gave at how to handle routes in Docpad
But I think what you are suggesting is more commonly done on the client side, so not really specific to Docpad (assumes jQuery).
if (location.search == "?c=thankyou") {
$('#message-sent').show();//show hidden div
setTimeout(function () {
$('#message-sent').fadeOut(1000);//fade it out after a period of time
}, 1000);
}
This is a similar answer I gave in the following Docpad : show error/success message on contact form
Edit
A third possibility I've just realised is setting the document to be dynamically generated on each request by setting the metadata property dynamic = true. This will also add the request object (req) to the template data passed to the page. See Docpad documentation on this http://docpad.org/docs/meta-data.
One gotcha that gets everyone with setting the page to dynamic is that you must have the docpad-plugin-cleanurls installed - or nothing will happen. Your metadata might look something like this:
---
layout: 'default'
title: 'My title'
dynamic: true
---
And perhaps on the page (html.eco):
<%if #req.url == '/?c=thankyou':%>
<h1>Got It!!!</h1>
<%end%>

Sencha Touch - RESTful load() specific instance URL problem (Store/model)

It seems there is a problem with loading a specific instance (load() function) using the rest proxy in a model/store object. example:
Code:
Ext.regModel('User', {
fields: ['id', 'name', 'email'],
proxy: {
type: 'rest',
url : '/users'
}
});
//get a reference to the User model class
var User = Ext.ModelMgr.getModel('User');
//Uses the configured RestProxy to make a GET request to /users/123
User.load(123, {
success: function(user) {
console.log(user.getId()); //logs 123
}
});
This code is copied from Sencha touch's API. the generated URL is http://localhost/users?_dc=... instead of the desired (and documented) url http://localhost/users/123.
it also happens when using the store.load with a parameter.
Am I doing something wrong here?
Thanks
T
It seams the id parameter has been documented but not implemented. This has been discussed in the sencha forum [link]. A few non complete fixes are written in post #8 and post #13.