Correct way to generate idiomatic rails controller? - ruby-on-rails

I'm learning rails 6 and walking through creating some toy resources. I know in my data model, I want to create a "widget" let's say, but I don't want everything that a scaffold is going to produce, so I'd like to manually generate everything that I know I'll need and nothing more. I started with a simple model. Next I'm trying to generate the controller + views I know I'll need. I ran:
rails g controller widgets index new show delete
This ended up creating a router with the following routes:
get 'widgets/index'
get 'widgets/new'
get 'widgets/show'
get 'widgets/delete'
I'm surprised by this, I would have expected something similar to the routes that are generated by default with the scaffold:
things GET /things(.:format)
POST /things(.:format)
new_thing GET /things/new(.:format)
edit_thing GET /things/:id/edit(.:format)
thing GET /things/:id(.:format)
PATCH /things/:id(.:format)
PUT /things/:id(.:format)
DELETE /things/:id(.:format)
Am I using the correct generator command to accomplish what I described? Or is this something that I would just need to manually set up with my routes?
EDIT: I realized the action I'm actually looking for is :destroy, and not :delete

This is normal if you don't want to use scaffold, and for some routes they are need to be setup manually like the delete route, it is a delete request not get like the controller is generating (the controller always generate get requests because it expects a corresponding view)
You can use: resources :widgets, only: [:index, :new, :show, :destroy]
this will generate what you want because this is the convention used in rails

The Rails generators are really just for generating the needed files, for anything out of the ordinary you will have to manually change things.
You can add this to your routes.rb instead of that list of GETs
resources :widgets, only: [:index, :new, :show, :destroy]
Which will produce an output similar to what you have in your question if you do rails routes from the terminal.

Related

Overriding routes parameters with NIL in Rails?

Is there a way to use resource routing instead of writing the routes one by one if my methods for which the default expects parameters don't use parameters?
For example, if I had a routes file like below, the expected path for the update method would be like this: /cats/:id (docs)
# routes.rb
Rails.application.routes.draw do
resources :cats, only: [:create, :update]
end
However, I don't require any params for my update method, meaning the path should be /cats.
I know there's a way to rename the params and not use :id, but I didn't find anything on disabling them. I tried adding param: nil to the end of the line but it didn't work.
As I wrote initially, I know this can be done if I write the routes one by one like below. My question is whether I can use resources to do it. Thank you!
# routes.rb
Rails.application.routes.draw do
post 'cats', to: 'cats#create'
put 'cats', to: 'cats#update'
end
This is exactly the use case for singular resources. Quote from the Rails Guides:
Sometimes, you have a resource that clients always look up without referencing an ID. For example, you would like /profile to always show the profile of the currently logged in user.
Change our routing to
resource :cats, only: [:create, :update]
And the following routes will be created:
cats PATCH /cats(.:format) cats#update
PUT /cats(.:format) cats#update
POST /cats(.:format) cats#create
As far as I know, there is not, resource is just a helper to create the standard verb-based CRUD routes, if you want custom routes you need to define your update route the way you did in your second example, of course, you can still use resource for your create route and just pass only: :create.

Ruby on Rails using a POST method

I'm trying to follow this guide:
http://guides.rubyonrails.org/getting_started.html#hello-rails-bang
and in section 5.7 it says to add this line.
post GET /posts/:id(.:format) posts#show
What does this do, and where should I put it? I tried putting it in the "create" method that follows this form:
http://dixonc3-72812.use1.nitrousbox.com/posts/new
I also tried putting it in the "view" because I figured it was accepting the "POST" method. How do I proceed? New to Ruby on Rails and trying to figure out the kinks.
I'm trying to follow this guide:
http://guides.rubyonrails.org/getting_started.html#hello-rails-bang
and in section 5.7 it says to add this line.
post GET /posts/:id(.:format) posts#show
Section 5.7 doesn't tell you that. What it tells you is the following is output of rake routes for the show action:
post GET /posts/:id(.:format) posts#show
The output is presented in a tabular format where the four columns are (from left to right): Prefix, Verb, URI Pattern, Controller#Action.
In order to get this, you need to declare posts as a resource in config/routes.rb as:
resources :posts, only: [:show]
Now if you run rake routes in your terminal, you will see the line included from the guide.
The above line in config/routes.rb defines a route for the show action. You can remove only: [ :show ] option to have routes defined for all standard RESTful actions, i.e. in your config/routes.rb:
resources :posts
This is the routes for show action of posts controller, for create action you find something like
posts#create

Simple Navigation Routing Error in Rails 3.2.8

longtime reader & first time poster, so I'd appreciate it if you went easy on me.
Recently started teaching myself RoR, and have been hacking away at a personal project/website to get the hang of things. Here's my problem:
I'm using the Simple Navigation gem to generate links. Inside navigation.rb I'm trying to call:
primary.item :home, 'Home', home_path
...where home is a view and controller that displays my front page:
home > index.html.erb (just contains a bunch of standard HTML, but let me know if it'd be useful to include)
and controllers > home_controller.rb:
class HomeController < ApplicationController
def index
#posts = Post.all
end
end
I'm getting this error, though:
Routing Error
No route matches {:action=>"show", :controller=>"home"}
Try running rake routes for more information on available routes.
... so I run rake routes, and can definitely see "home#show" in there.
My routes.rb file, as well, has this in it:
get "projects/index"
get "offer/index"
get "space/index"
get "home/index"
resources :posts
resources :home
So I'm a little baffled, and I'm sure it's because of my inexperience or general inability to understand what I'm doing, but I'd really appreciate some help as it's more or less a road block that I haven't been able to overcome.
Appreciate it!
Jay
It is because of the resources; if you are not using the resources remove resources :home
This could be your routes:
get "projects/index"
get "offer/index"
get "space/index"
get "home/index", :as => "home"
resources :posts
See how I removed the resources :home. In home/index the :as represents an alias, so you can use the alias as a method, adding "path" at the end of the name.
Check this guide about routes and resources: http://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default

Rails 3: Adding paths in routes for new controller?

I created a new controller for one of my models called Review, and named it review_controller, i put in show and update methods in it but cant get them working because rails didn't add the paths for the 2 methods.
I tried putting the follwoing in the routes file: match "/review/update/:id", :to => "review#update"
But it gives me a ActiveRecord::RecordNotFound (Couldn't find Review with ID=update):
app/controllers/review_controller.rb:16:in `update'
how can i add the path to the routes file to make my update and show methods work?
Thank You
For a new controller in Rails 3, you can let Rails build the routes for you like this:
resources :review, :only => [:show, :update]
And then if you were to run rake routes in the Terminal, you'd see:
review GET /review/:id(.:format) {:action=>"show", :controller=>"review"}
PUT /review/:id(.:format) {:action=>"update", :controller=>"review"}

Rails routes for article/234 and article/index

I need to setup the following urls:
/article (article#index)
/articles/1234 ( article#show with id 1234)
/articles/new (article#new)
Can I define this using:
resources :article do
???
end
If we look very closely at your question, it appears that you want the index to be at /article instead of the default Rails REST convention, which is /articles
It doesn't make any apparent sense to model your routes that way, but if that is surely what you want to do, then you could add one more route line in addition to the call to resources
resources :articles
match '/article', :to => 'articles#index'
It sounds like you're just learning rails. I'd suggest generating an article scaffold. It will set up a route like so for you:
resources :article
And you'll get RESTful routes setup for you automagically by rails
GET /articles index display a list of all articles
GET /articles/new new return an HTML form for creating a new article
POST /articles create create a new article
GET /articles/:id show display a specific article
GET /articles/:id/edit edit return an HTML form for editing an article
PUT /articles/:id update update a specific article
DELETE /articles/:id destroy delete a specific article
You can then dig into this and learn how rails does things.
Here's the official rails routing guide.
If you want those URLs and nothing else, you should put the following in routes.rb:
resources :article, :only => [:index, :show, :new]
In case you haven't stumbled upon the official Rails 3 routing guide, you should definitely take a look at it!

Resources