what is the difference between put and patch in rails? - ruby-on-rails

In rails the routes can be created using
resources :vehicals
so, that will create many routes which will produce the basic routes required for the CRUD operation, But I am confused between the 2 routes i.e.
PATCH /vehicals/:id(.:format) vehicals#update
PUT /vehicals/:id(.:format) vehicals#update
please clear which is to use while update.

In rails there's no effective difference, and you can see from your routes that they call the same controller action.
Because rails only updates fields that are included in the view form and leaves other fields unchanged, it effectively has always implemented "PATCH" logic even before 'PATCH' was ever officially introduced.
Current Rails forms default to method post for sending new records and patch for updating existing records.

Related

AJAX + Rails: Should I Use a GET or a PUT When Creating a Route?

My question: When using AJAX within Rails, from a best practice standpoint, does the HTML verb that I use (e.g., get) to define a route matter? Is it OK to basically always use get?
Context: In my Rails App, I've built the following:
When a user selects an HTML checkbox, that triggers a JQuery listener that lives in a file inside of /app/assets/javascripts.
This .js file makes an AJAX call to a controller/action: foos#bar. My JS passes an ID into the action.
To route this request, I've added the following to routes.rb: get "/foos/bar" => "foos#bar". This tells my App which controller/action should process the AJAX call.
The controller/action handles this request just fine. The action grabs the ID as a URL parameter, updates the relevant model object, and finally returns back a 200 to the JS AJAX caller.
This all works great! No issues -- nothing to troubleshoot here.
My question is: In the example above, is it appropriate to define a get route within routes.rb to process this AJAX request? Or, is that bad practice? Should I instead be defining a put, since conceptually that is what I'm doing in this workflow (i.e., I'm updating an existing object)? I'm worried that, while this all works perfectly, I'm breaking some fundamental MVC routing standards.
If you are updating a resource it will most likely be a PATCH update, which means you aren't completely replacing the resource but are just updating it (this is why PATCH is the default HTTP method for updates in Rails, instead of PUT).
So, yes, you are violating RESTful conventions by using GET to update a resource. GET is only used to fetch a representation of a resource...without changing it in any way.

Put or patch for new update action Rails

I want to add a new update(new_update) action in my user model of rails which will update a single column in the model. which rest api method I should use in routes file. Should I use put or patch or both.
resources: users do
member do
put 'new_update'
patch 'new_update'
end
If you want to match 100% with the HTTP verb definition.
PUT is supposed to overwrite your targeted resource entirely with the content in the request(all field non present in the request should be set to removed/nullified).
PATCH is supposed to only modify the fields sent in the request.
That being said, most of the time people don't make the difference and use either of them (a lot of people don't even know that there is a PATCH verb) is use PUT with the same behavior as PATCH (since the use case for PUT is quite rare on imo).

rails_3_question :as => why is my /posts/new routing to posts/show after setting up a slug

I'm using Rails 3 and after setting up slugs, I found that posts/new no longer works.
posts/:id, posts/:id/edit and all the other CRUD operations work.
However /posts/new gives me a routing error
No route matches {:action=>"show", :controller=>"posts"}
Now for some reason posts/new is routing to posts#show. In my routes, its just
resources :posts
My theory is that since /posts/:slug now matches against things other than numbers ids, the show verb is being routed to first. However it doesn't make sense since posts/grr a nonexistent entry gives a different error than posts/new and posts/first comes out just fine with all its associated paths working fine as well.
Anyone know what might be going on?
I've uploaded the repo to https://github.com/cultofmetatron/cassowary/tree/photogallary
I know my code sucks, I'm still learning the ins and outs of the system and I'd appreciate any insight into whats going on.
In your comment the first part seems fine: add a column to the Post column called slug and so on, and the contents of that will become some or all of the URL used to display a specific post. (I'll assume the other CRUD operations should work as normal)
To find the URL, the router has to know how to know which controller and action will handle this URL (as compared to others). A normal resources :posts route will match all of the RESTful methods, e.g. mapping a GET request onto a path starting with the controller name, and if an id is specified (/posts/1) map to the posts#show controller method, if not, it will map to posts#index method. If the request is a PUT, or DELETE or POST, different actions around a standardized URL format will occur.
Two changes are needed:
URL with the post slug format needs to map to the posts#show method (which is modified accordingly), and
Any links to the show page that are generated on your site need to use the post slug instead of the id
I'll assume you're OK with URLs start with /posts (if not, you'll need to identify some other unique pattern).
The first change requires that you override the specific case of the show method using route globbing, my adding something like match 'posts/*slug before the standard resource route. Here's a link to the guide on route globbing: http://guides.rubyonrails.org/routing.html#route-globbing
The next change, modify the existing posts#show method so that it looks for slug instead of id, e.g.
def show
#post = Post.where("slug = ?", params[:slug])
...
end
Finally, change the way Rails handles the URL helper posts_path. Do this by overriding to_param in your Post model, e.g.
def to_param
"/posts/#{slug}"
end
And then you're done. Maybe.
After that, see how the friendly_id gem does the same thing :-) https://github.com/norman/friendly_id

RoR Routes: Why does the app assume I want the show action with every URL?

So, I'm trying to access other actions in my controller, and it assums I want "show" every time, when I really just want... the action I just had in my URL.
this is in my routes:
map.resources :attachments
And when I do
domain/attachments/any_action?params
I get this error:
ActionController::UnknownAction (No action responded to show. Actions: {list of actions}
Using rails 2.3.8
I think I know what you are getting at.
Yes show is assumed for singular uses and index for plural.
This is a convention.
Much of the power / magic in rails comes from "convention over configuration" and this is one of them. Yes it could have been /attachment/show/ or /attachments/index but why not just eliminate the show and index if these are the most common and have them available as defaults and that is what rails does.
Now, as for actions not being available, lets look at that. First of all, right off the bat, please do a rake routes at the command line and see what you get. Also please indicate which actions you are trying. The restful setup "resources" will make 7 actions available:- index, show, new, create, edit, update and destroy, but not "any action"
The rule in Rails is first route matched, first route served.
Because you define a resource, it will consider everything like domain/attachments/whatever to be show action for the whatever stuff.
So two choices here:
define your other routes and declare them before the resource
nest your other routes inside the resource (I don't know how to do that in Rails 2.x)

Why is the scaffold generating routes like this? Why do they work?

The book "Agile development with Rails" shows in the second chapter, that you can say:
<%= link_to "Goodbye",say_goodbye_path %>
Instead of hardcoding the path to "/say/goodbye". Makes sense, I thought to myself. Probably Ruby is splitting the say_goodbye_path by _, assigns the first part as the controller name, the second part as the action name. But, afterwards, I generated the following scaffold:
rails generate scaffold User name:string mail:string
And I noticed in the index.html.erb view, that it had methods like: edit_user_path(user). I tried to rewrite it to user_edit_path(user), but of course, it didn't work. My question is, why are the scaffold links the other way around? How would I know if I should write them in the way the author uses them in link_to, or in the way they are generated by the scaffold. Can you shed some light on this?
The helper functions like user_edit_path are automatically generated by rails to map operations on resources to the matching routes and thus HTTP paths and HTTP verbs. You have to understand that you are dealing with resources here, not necessarily with simple controllers.
While most of the time your resources can map to a single controller, it doesn't have to be that way. You can have nested or combined resources which can result in rather complex routing definitions.
Resources are typically defined by giving it a name (userin this case) and defining some allowed operations on them. Rails encourages to follow the REST pattern there, so you can have shortcuts to have some operations pre-defined. One of them is edit, which by default matches to a GET request to users_controller#edit. Default operations on RAILS resources are:
HTTP verb path matching controller action
===================================================
GET /users #=> index
GET /users/1 #=> show
GET /users/new #=> new
GET /users/1/edit #=> edit
PUT /users/1 #=> update
POST /users #=> create
DELETE /users/1 #=> destroy
These mappings can be customized on your routes.rb (changing methods, adding or removing operations, ...) Generally you are encouraged to use the default mappings as these are supported by standard helpers and make your app easier to understand.
Scaffolds are code generated by a template which is not related to the routing.
Routing is based on the route.rb in your config folder. All resources are routed by default (when generated by scaffolds) but there's a default rule /:controller/:action/:id that you can enable. Think of a "catch all" case.
One way to see what routes to have is to edit route.rb and run rake routes and see how they change. There's an official guide here too: http://guides.rubyonrails.org/routing.html

Resources