Rails set show action rooting as post request - ruby-on-rails

In my rails app i have such route for carts controller:
resources :carts
so in layout, according to my logic i have:
= link_to "Моя корзина", #cart
and in browser i see for example:
******:3000/carts/112
Could i however do nested rails route show as post-like request? so i will have:
******:3000/carts/
also rake routes:
arts GET /carts(.:format) carts#index
POST /carts(.:format) carts#create
new_cart GET /carts/new(.:format) carts#new
edit_cart GET /carts/:id/edit(.:format) carts#edit
cart GET /carts/:id(.:format) carts#show
PUT /carts/:id(.:format) carts#update
DELETE /carts/:id(.:format) carts#destroy
cart POST /carts/:id(.:format) carts#show
I now how to write it for my own methods... But how to be with build-in show?
i need to change show route, so that id for show is sending not as get-param by url, but as post-param in request...

you could add routes like this (routes.rb)
Ex:
resources :carts do
member do
post :add
end
end
more about rails routes

The resources method simply puts in a bunch of predefined routes, as described here.
Specifically, it is adding the equivalent of
get '/carts/:id' => 'carts_controller#show'
post '/carts' => 'carts_controller#create'
...
If you want to use a different set of routes, don't use resources, and just define your own routes instead.
Also, you can't hide the cart id from the user this way. If the request contains the ID, it means that the user can see it. He might have to view it with Firebug or by looking at the page source instead of his address bar, but it's still not secret or protected in any way.

Just run rake routes in your console and see the routes you have.
Also you can read more about RESTful routes at http://guides.rubyonrails.org/routing.html#crud-verbs-and-actions

Related

How to access URL in Rails Show action in Controller

This is the URL I want to access in my show method
http://localhost:3000/students.1
but the error is coming
ActiveRecord::RecordNotFound in StudentsController#show
Couldn't find Student with 'id'=
def show
#student = Student.find(params[:id])
end
my routes are
new_students GET /students/new(.:format) students#new
edit_students GET /students/edit(.:format) students#edit
students GET /students(.:format) students#show
PATCH /students(.:format) students#update
PUT /students(.:format) students#update
DELETE /students(.:format) students#destroy
POST /students(.:format) students#create
root GET / students#index
Can someone tell me how do I access that students.1 in my URL so that I can display that particular student on my show page ?
Thats the wrong path. It should be /students/1.
And your routes are wrong. You can tell that the routes are off by the lack of an id segment and the fact that it maps GET /students to the show action instead of the index.
# Wrong
resource :students
# Right
resources :students
Pluralization is extremely important in Rails and is worth paying careful attention to. While its just one tiny letter these methods produce completely different routes.
resource is for singular resources. This is not the case here.
there is some issue with your route formation
your url is not properly forming , try below
students_path(id: student.id)
It should be http://localhost:3000/students/1
Check out this docs

How to get the sent parameters with POST (without form) on rails

I just only want to make a test and trying to understand the routes on rails. This is what I have on my controller:
class ItemsController < ApplicationController
def index
#data = params[:number]
end
end
and in index.html.erb
The number: <%= params[:number] %>
Well, if I made curl http://localhost:3000/?number=100 I can see on the view:
The number: 100
So, here everything is correct. But, I want to do the same, but with POST verb. So when I made curl -d "number=100" http://localhost:3000 I get the following error:
No route matches [POST] "/"
I have made:
def create
render plain: params[:number].inspect
end
to see the parameters, but as I said before, only works with GET verb.
So my question: How I can see the data sent by POST to the controller with curl and see the result on my view index.html.erb?
Note: On routes.rb I have:
Rails.application.routes.draw do
#get 'items/index'
resources :items
root 'items#index'
end
Notes: Based on the answer received, I have 2 more questions:
Why the verb GET works on http://localhost:3000/?number=100 and the same with http://localhost:3000/items/?number=100? Why the same does not happens with POST?
How can I remove the message No route matches [POST] "/" if the user points directly to http://localhost:3000 with POST verb?
You are posting to the root_url. Instead, POST your request to the items_url:
curl -d "number=100" http://localhost:3000/items
update:
Why the verb GET works on http://localhost:3000/?number=100 and the
same with http://localhost:3000/items/?number=100? Why the same does
not happens with POST?
The GET request to /?number=100 works because you have specified root 'items#index' in your routes file. This specifically creates a GET route that is mapped to the index action of the items controller.
How can I remove the message No route matches [POST] "/" if the user
points directly to http://localhost:3000 with POST verb?
You can create a single POST route using the post keyword:
# routes.rb
root 'items#index'
post '/', to: 'items#create'
which would generate the routes:
root GET / items#index
POST / items#create
(from your project directory run the command rails routes)
Or you can use the resource method to create all the CRUD paths:
resources :items, path: '/'
... which would create the following routes:
items GET / items#index
POST / items#create
new_item GET /new(.:format) items#new
edit_item GET /:id/edit(.:format) items#edit
item GET /:id(.:format) items#show
PATCH /:id(.:format) items#update
PUT /:id(.:format) items#update
DELETE /:id(.:format) items#destroy
Keep in mind that this may cause routing collisions if you try to add other resources to your app. If you need to add other resources, add them before these routes in the routes.rb file. Rails evaluates the routes file from top to bottom, so these resources would only load if no other paths match.
For more information see http://edgeguides.rubyonrails.org/routing.html

Is there a way to create a Rails resource route called `index`?

I want to add a resource route called index to a Rails 4 application but the generated routes aren't as expected. However, if I use another name (such as show_index), they are. To demonstrate, I'll begin with a vanilla Rails app that has no routes:
$ rake routes
You don't have any routes defined!
I add the below into config/routes.rb:
resources :items
Which produces the following resourceful Rails routes:
Prefix Verb URI Pattern Controller#Action
items GET /items(.:format) items#index
POST /items(.:format) items#create
new_item GET /items/new(.:format) items#new
edit_item GET /items/:id/edit(.:format) items#edit
item GET /items/:id(.:format) items#show
PATCH /items/:id(.:format) items#update
PUT /items/:id(.:format) items#update
DELETE /items/:id(.:format) items#destroy
The application has a show action that can render a so-called index if the parameter hash contains {with: 'index'} (this index is an application-specific thing, rather than a collection of items or anything like that).
I add a custom index route to invoke the show action with the additional parameter:
resources :items do
get 'index' => 'items#show', with: 'index'
end
This produces a new route but it has item_id instead of the expected id (compare with edit_item in the list above):
item_index GET /items/:item_id/index(.:format) items#show {:with=>"index"}
The Routing documentation explains that the way to get :id is to use on: :member, so the route would need to be
get 'index' => 'items#show', with: 'index', on: :member
but that doesn't produce the expected results. It adds the expected route but it steals the item method prefix from the default show action instead of using its own index_item (again, compare with edit_item in the list above):
item GET /items/:id/index(.:format) items#show {:with=>"index"}
GET /items/:id(.:format) items#show
However, had I used something other than index, such as show_index, then it would work as expected:
get 'show_index' => 'items#show', with: 'index', on: :member
produces
show_index_item GET /items/:id/show_index(.:format) items#show {:with=>"index"}
So there is a difference in behaviour when the route is called index. I expect this is because the implied resources routes use that name, although I don't think they use it in a way that would clash. It looks to me like I should be able to add a new index route which would become index_item (similar to the exisitng edit_item and in contrast to the existing item_index).
I know I can work around the problem, as I have demonstrated, by using a different name. But index reads better than show_index.
So my question asks is it possible to specify a resource route with index that is keyed off :id ?
`
To set specific url use as key word, so try something like:
get 'index' => 'items#show', with: 'index', on: :member, as: 'item_index'
or one of course on your wish.

newbie: how to get dynamic links for current_user?

Im trying to figure out how to get a dynamic link for example
/users/user1/show
/users/user1/edit
or
/profiles/1/
How would I create a route that I could insert in my views like a view_profile_path and that would include the id or username of a user?
in config/routes.rb you need to add 1 simple line:
resources :users
and get all this stuff
HTTP Verb Path action named helper
GET /users index users_path
GET /users/new new new_user_path
POST /users create users_path
GET /users/:id show user_path(:id)
GET /users/:id/edit edit edit_user_path(:id)
PUT /users/:id update user_path(:id)
DELETE /users/:id destroy user_path(:id)
You can read about rails routes in the guides
Actually, I think you need something like this in config/routes.rb
resources :users do
resources :profiles
end
You can later check your REST-ful resource routes by issuing the command:
rake routes
This way you have a more natural approach to your routes in which your users will be bound to one or more profiles, therefore you may use something like:
user_profile_path(#user)
to create an appropriate link to a user's profile.

Rails 3 restful route problem

The following link works in my app:
<%= link_to "invitation", :controller => :invitations, :action => :index %>
To follow restful conventions i changed the link to:
<%= link_to "invitation", index_invitation_path %>
The error that i get is:
undefined local variable or method `index_invitation_path'
Rake routes yields:
invitations GET /invitations(.:format) {:controller=>"invitations", :action=>"index"}
The page name is index.html.erb. The model is invitation.rb. The controller is invitation_controller.rb. Routes has resources :invitations. What am i missing?
Thanks!
Assuming you have the routing correct:
resources :invitations
Then the correct helper for the index action (with the url /invitations.html) is
invitations_path
You can see more information by running rake routes. It will display text like the following:
lists GET /lists(.:format)
{:action=>"index", :controller=>"lists"}
POST /lists(.:format)
{:action=>"create", :controller=>"lists"}
new_list GET /lists/new(.:format)
{:action=>"new", :controller=>"lists"}
edit_list GET /lists/:id/edit(.:format)
{:action=>"edit", :controller=>"lists"}
list GET /lists/:id(.:format)
{:action=>"show", :controller=>"lists"}
PUT /lists/:id(.:format)
{:action=>"update", :controller=>"lists"}
DELETE /lists/:id(.:format)
{:action=>"destroy", :controller=>"lists"}
root /(.:format)
{:controller=>"lists", :action=>"index"}
The above was from a route of my own (for a model called List). The route helper method is shown immediately before the HTTP method. You have to remember to append the _path to each helper method. For example the helper methods I could use are:
list_path(list)
edit_list_path(list)
new_list_path
lists_path
You'll need a route in your routes.rb file that defines a mapping to the invitations controller and the index action.
Typically this is created with a resources call
resources :invitations
Which creates several default routes, which you can see by running rake routes.
For single resources, you can also define it using a match call
match "invitations/:id" => "invitations#index", :as => index_invitation
The rails site has a great resource on routing that provides all the details: Routing from the Outside In
Update: Based on your updated question, your route includes an invitaions (notice the trailing 's') route - nothing with index or invitation. The index_ prefix is generated by the resources call when it creates the default routes for :invitations.
It looks like you've defined a custom get mapping for an invitation. While this may technically work, if you're aim is to support restful routes, use the resources method. And have a read of the Routing guide from rails it's very easy to follow and quite detailed.
type rake routes in your console and look at listing of available routes. Seems to be there is no such route index_invitation_path? maybe it named differently
I think you need "invitations_controller.rb" to contain InvitationsController. Plural.

Resources