How to change routes in ruby on rails? - ruby-on-rails

I just installed Ruby on Rails and created a scaffold called posts. RoR generated controllers and other required files for me.
I created a new method in posts_controller, but I can't access it. I looked at other methods that are in the controller and looks like I need to access them by /posts/[MY POST ID]/[MY METHOD NAME].
Assuming I created my custom method hello in the controller, how do i access it?
I looked at routes.rb, but there's no configuration for it.
Updated:
I understand that I can manually configure it in routes.rb, but how do all the other methods work? For example, I have "edit", and "update" methods in the "posts_controller.rb" controller. How do those two methods work without configuring routes?
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
I can't find a configuration that matches /posts/[0-9]/edit pattern.

The documentation you're looking for is Rails Routing From the Outside In. Once you've read this you'll understand everything Rails does to take your request and point it at method in your controller.

You need to add a route for it to routes.rb. For example:
# Previous routes
# resources :posts
# Updated routes
resources :posts do
get "hello", :on => :member
end
Have a look at this Rails guide about routing, it should help you understand Rails routing.

This will give you a good head start on the routes: http://guides.rubyonrails.org/routing.html
Not every method you make will have its own path, rails is built on the rest principle, and your scaffold created methods in the post controller that follow those paths, like index, show etc....
You can force your method to have a route added to it, but in reality you rarely actually need to do so as following the convention is far easier.

In Rails 3.x
match 'posts/hello' => 'posts#hello'
Available at example.com/posts/hello

When you used scaffold to generate post, it added a line resources :posts in your routes.rb file. That line configures routes for all the controller actions that were generated. As Caleb mentions above, not every action has a dedicated path. A single path can correspond to multiple actions because rails also takes into account the HTTP method. So, for instance, the path /posts with the HTTP method GET corresponds to the controller action index, while the same path with the HTTP method PUT corresponds to the controller action update. You can see these associations when you run rake routes from the console. I agree with Jordan and Caleb that the Rails Guides is a good read and will help you understand routes.

Related

Rails: Some index routes are showing "/controller_name/index" others are just showing "/controller_name"

I'm really confused because some of my routes when I use controllername_index_url are routing to /controllername/index while other's are routing to /controllername.
The main difference is that when I generate the index method when I create the controller through the command line
rails g controller controllerName1 index
the route then becomes /controller_name_1/index.
When I create the index manually after creating the controller, it becomes /controllername2
In my config/routes I am including my controllers like:
Rails.application.routes.draw do
resources :controller_name_1
resources :controller_name_2
end
And when I do a rails routes my routes look like
controller_name_1_index GET /controller_name_1/index(.:format) controlle_name_1#index
controller_name_2_index GET /controller_name_2(.:format) controller_name_2#index
Why is it automatically adding the routes differently? How can I make it so that regardless of it I generate the index methods on the command line or add them in after the fact, controller_name_index_url routes are always the same format? (I'm using ruby 2.4.0 and rails 5.1.2 if that's helpful)
When you create an action at the command line a route is automatically generated for it.
$ rails g controller ones index
create app/controllers/ones_controller.rb
route get 'ones/index' # route helper is ones_index
...
The behavior is totally agnostic of the action you're creating. It could be any action name and Rails will do the same thing
$ rails g controller twos smorgas
create app/controllers/twos_controller.rb
route get 'twos/smorgas' # route helper is twos_smorgas
...
When you add resources to your routes
resources :ones
you automatically get all of the default REST route helpers and routes, no matter how you create any of the REST actions.
$ rake routes
ones GET /ones(.:format) ones#index
POST /ones(.:format) ones#create
new_one GET /ones/new(.:format) ones#new
edit_one GET /ones/:id/edit(.:format) ones#edit
one GET /ones/:id(.:format) ones#show
PATCH /ones/:id(.:format) ones#update
PUT /ones/:id(.:format) ones#update
DELETE /ones/:id(.:format) ones#destroy
It's best to stick with Rails convention and use the default route helpers
ones_url
ones_path
# not ones_index_url
See this SO question if you want to disable the automatic route generation

Rails Tutorial- cannot get rails to recognize route

I am new to programming in general, someone referred me to railstutorial.org.
Specs: I am working on a cloud9 IDE, as suggested in the tutorial.
Information: I am on 1.3 of the rails tutorial, which is setting the root route.
The problem was initially my route did not effect the server launch (root page was still ruby default, not to 'application#hello'). Here are the files that the tutorial said to edit.
routes.rb
Rails.application.routes.draw do
root to: 'application#hello'
end
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def hello
render text: "Hello, world!"
end
end
There are a lot of comments that were defaulted into the files that I left out.
I have followed the instructions precisely. After I first had trouble, I thought I may have made an installation error, so I deleted my IDE and restarted, paying extreme attention to detail, especially versions.
I have tried $ rake routes, and my understanding it gives the message:
You don't have any routes defined!
That leads me to believe that the problem is the routes.rb file. I have tried changing the syntax to:
root to: 'application#hello'
I don't know a whole lot, such as how it would work using application, so I also tried:
root 'ApplicationController#hello'
and
root to: 'ApplicationController#hello'
These all result in the no routes defined message. I have no idea what is going on.
Thanks for any input or help!
You could try root 'application#hello' in your routes. Also, when starting out simple things like forgetting to save the file before trying things out on the browser can slip by; restarting the server takes care of a surprising number of foibles.
The rails documentation can also provide you a bit more information beyond the tutorial.
You probably want to move that action outside of the ApplicationController to another controller, but if you really insist, you can put this into your routes.rb:
get '/hello', to: 'application#hello', as: :hello
If you want the page to be the root, I would recommend creating a StaticPagesController and defining hello there, instead of putting it inside ApplicationController.
Here's what you can do:
Run rails g controller static_pages
Inside your StaticPagesController.rb, copy and paste your hello method that was inside ApplicationController.
Change the routes.rb to root 'static_pages#hello.
and you should have your desired result.
I've followed the same tutorial and I can say that the materials covered in the first two chapters are quite complicated at first if you are new to programming. It's only after you've done the entire tutorial that it will become clear to you how this routing thing (or any other details in these chapters for that matter) actually works.
However, since this idea of routing is very important, it's not a bad idea to understand how it works even if you are at an early stage in the tutorial.
The way you can create a route in rails is that you first specify a proper HTTP verb (GET, POST, PATCH, DELETE) with an appropriate path, the name of a controller, followed by a hash sign (#) and the name of an action defined in the controller.
Here controller is just a ruby class and an action a ruby method. (Since the basic principle of ruby on rails is "convention over configuration", it's important to get used to the terminology like controller, action, routing etc...)
When you say
get '/hello' => "application#hello"
(yes, you can use => in place of to:) as takeriho suggests, what happens is that a GET request to a URL of the type /hello(/ being "root path" as in www.example.com/(note the / at the end)) will get routed to the action, or method, named hello defined in a controller, or a class, named ApplicationController.
If you take a look at application_controller.rb, you can see that a method hello is defined within a class ApplicationController.
class ApplicationController < ActionController::Base
.....
def hello
render text: "Hello, world!"
end
end
Now if you want to specify a root route, which is your original question, you can just do root followed by the name of a controller, a hash sign (#), and the name of a class. So the code
root "application#hello"
means that a request to a url of the form /, or a root_path as it's called in rails convention, will get routed to the action (or method) named hello defined in a controller (or a class) named ApplicationController. You could accomplish the same result by doing
get '/' => "application#hello", as: :root
(you can name a route by adding as: :custom_name) but rails is smart enough to know that the two are equivalent. The task is made easier by following the rails conventions.
If you are completely new to Rails, I highly suggest you check out the Rails courses in Pragmatic Studio before going through the Ruby on Rails Tutorial which, as the author suggests, is not for a complete beginner. This approach worked perfectly for me. The rails courses offered by Pragmatic Studio assumes you have no prior knowledge about programming, and explains the basics in a manner much clearer than I did in this answer.
Happy coding :)

Routing Error Ruby on Rails

I've installed ruby on rails 3.2.6, and when I execute
rails server
and access to 127.0.0.1:3000 it works, however when I generate a controller, for example
rails generate controller principal
and access to 127.0.0.1:3000/somecontroller, browser show following error:
Routing Error
No route matches [GET] "/principal"
Try running rake routes for more information on available routes.
What do I need to do, and can this be simply explained?
The problem is you did not specify any actions, so your controller 'principal' is empty, no views will be created with similar names, and no routes created.
You need to do:
rails generate controller principal index [show] [edit] [update] [create] [destroy]
The name after your controller name are the action names. Since you said controller 'principal' in the singular, then it might imply that you have a singular resource. If you want to have it in the plural, make sure you say 'controller principals'.
And your routes should should show:
resource :principal [ or :principals or multiple Restful routes ]
You need to edit config/routes.rb to tell the router which controller to route your request to. The rails standard is to use RESTful routes and in the example you've given this would equate to a singular Principal resource. Therefore you'd need to add:
resource :principal
to generate a set of RESTful routes for this resource. You can see the routes generated by doing:
rake routes
If you don't care about REST then you can simply add (assuming the PrincipalController has an index method):
match 'principal' => 'principal_controller#index'
Have a look at this chapter from the Rails Guides for more info on routing:
http://guides.rubyonrails.org/routing.html
You can also generate methods in the controller and routes at the same time by supplying their names as arguments to the rails generate controller command for example:
rails generate controller principal index

rubymine generate routes.rb

I am new to Ruby on Rails and have some problems.
For the development I use RubyMine IDE, I manage to create models, controllers and views, but I have problems with the routing. By default, routes.rb file contains only this method Apis::Application.routes.draw do with an empty body.
For example, I create a controller TestController, then the index method and in routes.rb I add this instruction resources :test. So far, it works fine. But if I add another method, let's say method1 (and the view) I can't reach it in a browser http://localhost:3000/test/method1.
What else should I add in routes.rb file?
Is there any way to make the routing automatically from the IDE, with less editing the routes file?
resources :test
is a resourceful route which provides a mapping between HTTP verbs and URLs to controller actions. By convention, each action also maps to particular CRUD operations in a database
you can uncomment in your routes to enable the controller action mapping.
match ':controller(/:action(/:id(.:format)))'
or use -
match "/test/method1" => "test#method1"
Detailed routes info # http://guides.rubyonrails.org/routing.html

How to configure routes.rb to route any action

I'm tired of creating a new line in my routes.rb every time I add a new method in my controller. Is there a way in routes.rb to tell rails to accept any defined action in a given controller? I'm pretty sure I've done this before but can't remember how. I still need to explicitly specify the controller, however, because many other people use this routes file.
Thanks!
This is from the default generated config/routes.rb file
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'

Resources