rails RESTful updates - ruby-on-rails

In Rails, should you be able to update a field using a URL.
Is that called RESTful?
For example, should something similar to this work to update workorder.wostatus_id for workorder with id=2?
http://localhost:5000/workorders/2?wostatus_id=4
Thanks!

In the case you've provided that shouldn't work as updates should be performed via a PUT request although if the URL was requested via PUT then it should work.
Remember the idea is that:
GET to access and retrieve data
PUT to update data
POST to create data
DELETE to remove data
EDIT: Often the actual parameter names can vary depending on the controller implementation so in rails you often find ?workorder[wostatus_id]=4, where it will reference the model name.

You will have to call a URL to perform any updates, but you'll need to use a POST or PUT request. POST to create, PUT to update, but I believe Rails uses "data-action" attribute for PUTs, then actually calls POST behind the scenes.
Just putting the URL in a browser, like the one you gave, will by default perform a GET request, which should never be used to change data, only to retrieve it.
Here's a good tutorial that explains the basics of REST: REST API tutorial
The Rest for Rails screencast is pretty helpful, as well.

Related

where do I put an API curl request in a rails app

I'm using the G Adventure API to populate a database in my super-basic rails app.
The docs https://developers.gadventures.com/docs/index.html#api-endpoint
say to use a CURL request to get back JSON data, which obviously works fine, but what I'm wondering is where I should then store this request in the app itself...
Hunch is that it should be linked to a method inside the controller?
Thanks.
You don't really want to use curl in the application. Instead it would be better to use Ruby's Net::HTTP to make the request. Also, if relates to the logic of your app, and if you are saving the data in a database, it sounds like it does, this sort of thing belongs on the model, not the controller.
So in your model try
Net::HTTP::Get.new(API END POINT URL)

Rails routing, deep nesting for external resources

I understand that it's a good practice to only include in the URL the parameters needed to determine the object of the model.
If I have 2 models, Post and Comment... a Post has many comments and a comment belongs to one post. A URL for a comment can be
/comment/:comment_id
and from associations I can determine which Post it belongs to but
Some rails apps need to access external resources(Via APIs for example). If the rails app needs to replicate a part of another external source, what is the right way to handle URLs and routing?
If for example a post has some comments, The URL for a comment can be
/post/:post_id/comment/:comment_id
or
/comment/:comment_id
The latter has one disadvantage which is that I can't determine which post it belongs to if the API of the external source doesn't determine that and this would cause some problems with navigation through the app but it's a short URL and allows the user to easily manipulate the URL to get another comment(which I see as an advantage). At the same time using the first(long) link would make the URL so long but I can know which post it belongs to.
The only solution I can think of is to make both possible but the user would never know that the short one exists if I make the long one the default. What do you think?
I always use the longer / spelled-out version myself. I don't mind that it's long and I can only see good things come from it as you're discovering here. I also think it's an advantage because then you can do things like this:
post = Post.find_by_id(params[:post_id])
comment = post.comments.find_by_id(params[:id])
The point being that you can't go "comment fishing" this way. You have to have the right post context in order to get at a specific comment. This may not matter a whole lot if comments aren't at all sensitive, but there are many thing in a web app that may be. So scoping finds by a root object (like post here) allows a quick permissions check that can be reused and without having to check on parent objects.
Anyway, that's my 2 cents. I never understood why people take offense to the longer urls. If they work for you then don't be afraid to use them!

Play Framework - GET vs POST

New to web development, my understanding is that GET is used to get user input and POST to give them output. If I have a hybrid page, eg. on StackOverflow, if I write a question, it POSTs a page with my question, but also has a text box to GET my answer. In my routes file, what method would the URL associated with my postQgetA() method specify - GET or POST?
From technical point of view you can use only GET to perform almost every operation, but...
GET is most common method and it's used when you ie. click on the link, to get data (and do not modify it on server), optionally you send id of the resource to get (if you need to get data of single user).
POST is most often used to sending new data to the server ie. from form - to store them in your database (or proccess in any other way)
There are also other request methods (ie. DELETE, PUT) you can use with Play, however some of them need to be 'emulated' via ie. ajax, as there is not possible to set method of the common link ie. to DELETE. It's described how to use non-GET/POST methods in Play! (Note, that Julien suggests there, using GET for delete action although is possible it's a broken semantics.)
There are also other discussions on StackOverflow where you can find examples and suggestions for choosing correct method for your routes.
BTW, if you sending some request, let's say it's POST you don't need to perform separate GET as sending a request generates a response in other words, after sending new question with POST first you're trying to save it to DB, if no errors render the page and send it back in response.

PUT vs. POST for Uploading Files - RESTful API to be Built Using Zend Framework

I'm building a RESTful API using Zend Framework via the Zend_Rest_Route. For uploading of files, should I use PUT or POST to handle the process? I'm trying to be as consistent as possible with the definition of the REST verbs. Please refer to: PUT or POST: The REST of the Story.
The way I understand this is that I should use PUT if and only if I'm updating the full content of the specified resource. I'll have to know the exact URL to use PUT. On the other hand, I should use POST if I'm sending a command to the server to create a subordinate of the specified resource, using some server-side algorithm.
Let's assume this is a REST API for uploading images. Does that mean I should use POST if the server is to manipulate the image file (i.e. create thumbnail, resize, etc); and use PUT if I just want to save the raw image file to the server?
If I use PUT to handle a file upload, should the process be as follows:
The user sends a GET request to retrieve the specific URL to upload the file by PUT.
Then the user sends a PUT request to that URL.
The file being uploaded is raw - exactly the one the user uploaded.
I'm quite new to this stuff; so hopefully I'm making sense here...
If you know the "best" way to do this, feel free to comment as well.
There seems to be quite a bit of misunderstanding here. PUT versus POST is not really about replace versus create, but rather about idempotency and resource naming.
PUT is an idempotent operation. With it, you give the name of a resource and an entity to place as that resource's content (possibly with server-generated additions). Crucially, doing the operation twice in a row should result in the same thing as if it was done just once or done 20 times, for some fairly loose definition of “the same thing” (it doesn't have to be byte-for-byte identical, but the information that the user supplied should be intact). You wouldn't ever want a PUT to cause a financial transaction to be triggered.
POST is a non-idempotent operation. You don't need to give the name of the resource which you're looking to have created (nor does a POST have to create; it could de-duplicate resources if it wished). POST is often used to implement “create a resource with a newly-minted name and tell me what the name is” — the lack of idempotency implied by “newly-minted name” fits with that. Where a new resource is created, sending back the locator for the resource in a Location header is entirely the right thing to do.
Now, if you are taking the policy position that clients should never create resource names, you then get POST being the perfect fit for creation (though theoretically it could do anything based on the supplied entity) and PUT being how to do update. For many RESTful applications that makes a lot of sense, but not all; if the model being presented to the user was of a file system, having the user supply the resource name makes a huge amount of sense and PUT becomes the main creation operation (and POST becomes delegated to less common things like making an empty directory and so on; WebDAV reduces the need for POST even further).
The summary: Don't think in terms of create/update, but rather in terms of who makes the resource names and which operations are idempotent. PUT is really create-or-update, and POST is really do-anything-which-shouldnt-be-repeated-willy-nilly.
For file upload, unless it is replacing an existing resource, definitely use POST.
In REST, POST is to create new resources, PUT to replace existing resources, GET to retrieve resources, and DELETE to delete resources.
Source: http://en.wikipedia.org/wiki/Representational_state_transfer#RESTful_web_services
REST isn't a standard so this can easily turn into a religious battle. AtomPub and OData standards which are considered to be "RESTful" do agree on this though: POST = creation while PUT = updates
The simple answer is you should use PUT instead of POST in your case since you will be replacing the entire content of the file. Take a look at PUT vs POST
I'll have to know the exact URL to PUT
to
No. You dont have to know the URL to PUT i.e. the PUT URI needn't be present before the PUT operation. If the resource doesn't exist, the resource is created. If the resource is already present, then the resource is replace with the new representation.
To quote the linked article:
PUT puts a page at a specific URL. If
there’s already a page there, it’s
replaced in toto. If there’s no page
there, a new one is created. This
means it’s like a DELETE followed by
an insert of a new record with the
same primary key

Generic Back Functionality

I need to implement back functionality in my project, for this what i am doing that i am maintain last url in ViewData["RetUrl"] and on next page i am getting previous url from that ViewData["RetUrl"].on this way i had implemented this functionality.This idea is failed when level of pages increased i mean page1>page2>page3, no way to back page3 to page1.i can aonly able to maintain 1 level.
Now i am thinking for a generic kind of implementation which i can easily implement on my next project.Please help me with your idea about this...
I am working on ASP.NET MVC.
It also gets complicated if you recall that not all page requests are GET bit include some POST and possibly other verbs.
I once wanted to do something similar but then abandoned the idea. It's not really that needed. As an idea on how to approach the problem...
At each request record the current page and the verb together in pair like:
GET /users
GET /users/add-user
POST /users/add-user
GET /users
You can store this information in the TempData collection, read it at each request and update it by adding current request details. Then you implement some framework method that will scan the collection skipping all POSTs (or whatever you need) and give you the previous GET url.

Resources