How to access URL in Rails Show action in Controller - ruby-on-rails

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

Related

Rails custom routes with scopes

I have a scope 'games-posts' in my Post model that fetches posts that belong to a Topic with a title "Games" (Post belongs_to Topic). In my routes I have defined the route get 'games-posts', to: 'topics#games' and have the view where I show the list of those games posts. In each of the posts I have a link that takes me to that specific games post.
Apart from that I have regular resources :posts routes that the generate standard urls:
`/posts`
`/posts/:id`
`/posts/:id/edit`
etc.
My problem is that when I click on a specific post on games-posts page right now it redirects me to /posts/1 (for example).
It would be cool if it redirected me to /games-posts/1 instead of /posts/1 and similarily I would like to edit and destroy those posts from games-posts page. How can I accomplish this? Is it possible to define something like
resources :games-posts?
The :controller option lets you explicitly specify a controller to use for the resource. For example:
resources :games_posts, controller: 'posts'
Now run rake routes and you will get following output to verify if it generated your required paths.
games_posts GET /games_posts(.:format) posts#index
POST /games_posts(.:format) posts#create
new_games_post GET /games_posts/new(.:format) posts#new
edit_games_post GET /games_posts/:id/edit(.:format) posts#edit
games_post GET /games_posts/:id(.:format) posts#show
PATCH /games_posts/:id(.:format) posts#update
PUT /games_posts/:id(.:format) posts#update
DELETE /games_posts/:id(.:format) posts#destroy

Resource route in ruby and rails

I have
resources :blog
declared in my routes.rb file but when I try to access blog_path in a controller or a html.erb file, I get the following error:
No route matches {:controller=>"blog", :action=>"show"} missing required keys: [:id]
I have created a controller called BlogController and defined the method show with a show.html.erb file in the views directory. If I define:
match '/blog', to: 'blog#show', via: 'get' instead, then blog_path works fine.
My understanding is resources: blog is just syntactic sugar for match '/blog', to: 'blog#show', via: 'get' and a bunch of other routes. Please help.
blog_path is for generating path to a blog, so you need id or a blog object, this helper generates path like /blogs/12 to blogs#show, and blogs#show is for showing an object. blogs_path generates /blogs to blogs#index (like to all blogs).
Look at 2 Resource Routing: the Rails Default
resources :photos
GET /photos index display a list of all photos
GET /photos/new new return an HTML form for creating a new photo
POST /photos create create a new photo
GET /photos/:id show display a specific photo
GET /photos/:id/edit edit return an HTML form for editing a photo
PATCH/PUT /photos/:id update update a specific photo
DELETE /photos/:id destroy delete a specific photo
You have used resources :blog without s. It generates
blog_index GET /blog(.:format) blog#index
POST /blog(.:format) blog#create
new_blog GET /blog/new(.:format) blog#new
edit_blog GET /blog/:id/edit(.:format) blog#edit
blog GET /blog/:id(.:format) blog#show
PUT /blog/:id(.:format) blog#update
DELETE /blog/:id(.:format) blog#destroy
Make resource plural like this
resource :blogs
And make controller name blogs_controller.rb and its class name BlogsController
This is rails standard
I'm recently starting to use Rails, but I noticed that when Rails generates a controller for me, it names it with an underscore between the name and the word controller.
Something like blog_controller.rb. A few days ago I replaced one with other without the underscore and get a similar error, not sure why.

Does every belongs_to has_many association need nested routes?

This is a fairly basic question but I haven't been able to find concrete answers online. Every has_many belongs_to does not need nested routes correct? Should you only use nested routes when you're looking for URLs of the form class/:id/class/:id?
For example, let's say I have two classes Profile and Post.
models/profile
has_many :posts
models/post
belongs_to :profile
There's no separate post URL, the posts are displayed in profiles/show. Should the post routes (in this case it would be only actions like :new, :create, and :destroy) be nested inside the :profiles resource? The rails guide states that resources should not be nested more than one level deep and there are often times. Making nested resources for every association seems like it would violate this rule very quickly. Thanks in advance!
If you have no use for /profile/1/posts or /profile/1/posts/1 you do not need the nested routes. However, I urge you to rethink, nested routes make for clean RESTful APIs
For example, the neat little nested route:
resources :profile, :shallow => true do
resources :posts
end
will give you all these realy useful routes:
profile_posts GET /profile/:profile_id/posts(.:format) posts#index
POST /profile/:profile_id/posts(.:format) posts#create
new_profile_post GET /profile/:profile_id/posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
profile_index GET /profile(.:format) profile#index
POST /profile(.:format) profile#create
new_profile GET /profile/new(.:format) profile#new
edit_profile GET /profile/:id/edit(.:format) profile#edit
profile GET /profile/:id(.:format) profile#show
PUT /profile/:id(.:format) profile#update
DELETE /profile/:id(.:format) profile#destroy
This way you have to freedom to choose the nested route when necessary/useful, such as
GET /profile/:profile_id/posts/new(.:format) # create a new post for the given profile_id
GET /profile/:profile_id/posts(.:format) # return all posts for the given profile_id
and use the shallow routes where the nested routes are not necessary
If you read Section 2.7 of the Ruby on Rails Guide it states that:
Nested routes allow you to capture this relationship in your routing.
See - http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default for reference.
Further to this you may want to perform particular operations on a class i.e. user which has create, edit etc ... every user is associated with a particular booking. That means that whenever you do anything to a user, you really are doing something to an user/booking. Because this is associated with this.
RESTful routes is a clean way of setting your application and making good use of unified resource identifiers. An example of this would be identifying a particular user such as /users/1/bookings/3 this would show the first user.

Rails set show action rooting as post request

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

Rails routing problem, resources, resource ,or get?

With the following routes:
resources :locations do
resources :newsitems
resource :weather
get 'weather'
end
I don't have a named route for the get action on weather:
location_weather POST /locations/:location_id/weather(.:format) {:action=>"create", :controller=>"weathers"}
new_location_weather GET /locations/:location_id/weather/new(.:format) {:action=>"new", :controller=>"weathers"}
edit_location_weather GET /locations/:location_id/weather/edit(.:format) {:action=>"edit", :controller=>"weathers"}
GET /locations/:location_id/weather(.:format) {:action=>"show", :controller=>"weathers"}
PUT /locations/:location_id/weather(.:format) {:action=>"update", :controller=>"weathers"}
DELETE /locations/:location_id/weather(.:format) {:action=>"destroy", :controller=>"weathers"}
What do I have wrong here? I put the weather in there as both get and resource, but I really want to just have it as an action on my locations controller, as its not actually a separate resource. Any ideas what I'm doing wrong?
If weather truly is not a separate resource then you might not want to use it in the URL and just call locations/:id to retrieve the weather for that location. However, if you are doing other things with locations - as I suspect you are - you should probably go ahead and create a resource for weather. It doesn't need to have anything in it other than the show method, but it's good to have just for inventory purposes and to be RESTful.
Try the following. I think it will provide you what you are looking for:
resources :locations do
matches "weather" => "weather#show"
end
Just delete the 'resource :weather' and you'll get your location_weather route. If all it is is a custom action on the Locations controller that will handle it.

Resources