Rails activation route - ruby-on-rails

I am learning rails and routing has me wanting to jump off the roof.
I am confused on how to go about routing my activation at this point.
I have the following currently in my user routing:
resources :users, only: [:new,:create,:show]. Now I want a route to Users#activate like this www.app.com/users/activate/:a_long_token. Now I know I can just simply do a match '/activate/:auth_token', to: 'users#activate but I am not sure whether this is convention. I was reading this guide on user authentication but it seems its routing is rails 2. Can I do something to add the route mentioned above by simply adding something to the resource itself. By that I mean doing something like (I know this won't work)
resource :users do
member do
get :activate
end
end

rails3 guide
http://guides.rubyonrails.org/
http://guides.rubyonrails.org/routing.html
resources :users do
collection do
get "activate/:a_long_token" => "users#activate", as: :activate
end
end
rake routes outputs this
activate_users GET /users/activate/:a_long_token(.:format) users#activate

Related

Rails how to make example.com/post/1 to example.com/blog/post/1

I have a blog with root
root 'posts#index'
And works best with example.com/ to example.com/posts
But what I want is something like this:
example.com/blog/posts/1.
I've tried creating blog Controller and add
resources :blog do
resources :posts
end
But this is making my routes to blog/:id/posts/:id
If you don't have the relationship between the post and the blog as you mentioned, rails gives you the freedom to declare routes as our own.
so, to make the route example.com/posts/1 to, example.com/blog/posts/1, just add a custom route at the last.
get '/blog/posts/:id', to: :show, controller: 'posts'
what this does is over rides the previous route and make this route final.
Now type rake routes and it will give the last route for you as,
GET /blog/posts/:id(.:format) posts#show
Now you can access using,
example.com/blog/posts/1
Reference for rails routing
Just to expand upon #Sravan answer. If you have multiple routes that will start with /blog/ you might want to check Rails guide on routing.
You can add something along the lines of
scope '/blog' do
resources :posts
resources :users
resources :images
end
Which will create corresponding routes under /blog/.
namespace :blog do
resources :posts
resources :users
resources :images
end
And your controller with namespace will look like this: Blog::PostsController

Rails "/blog" path uninitialized constant Blog

I am trying to setup a rails blog at the "website.com/blog" url
I already have my models and controller setup to work to where going to
website.com/posts
Gives me all my posts and going to
website.com/posts/1/
Shows me that post, etc, etc. What I want to happen is that when I go to
website.com/blog/
I should see the posts index (and the original URL should no longer work). Similarly I want to go to
website.com/blog/posts/1/
To see that post and so on and so forth.
Right now this is my routes file:
Rails.application.routes.draw do
namespace :blog do
resources :posts do
resources :comments
end
end
get "/blog", to: "posts#index"
end
When I go to "/blog/" I get a Routing Error saying "uninitialized constant Blog". Do I need to create a blog model and controller and migrate to complete this? I'd rather not since it's really just running the posts requests from that new URL. Am I going about this the wrong way?
I ended up finding the answer to my own question here: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
Using this seems to work just fine:
scope '/blog' do
resources :posts do
resources :comments
end
end
get "/blog", to: "posts#index"
The answer ended up being found here: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
As usual the solution was incredibly simple and made me feel like an idiot for not knowing what to do immediately:
scope '/blog' do
resources :posts do
resources :comments
end
end
get "/blog", to: "posts#index"

In RoR, do I have to specify every controller method as a route by hand?

What I'm wondering, in this case where I want to create a few web service type controllers, is if there is a way to "export" what method is allowed to be called from the controller. I'm still very new to RoR, and its routes feature, but in the end, is it expected that a fully functional RoR application just has hundreds of routes? Not every controller method I'm creating falls into a "resource" category.
Rails routes come in several varieties – RESTful routes are merely the ones that happen to provide native support for Rails resources. Remember that event resource routes can be modified to have member and collection routes:
# routes.rb
resources :products do
member do
get 'short' #=> products/:product_id/short/:id
post 'toggle' #=> products/:product_id/toggle/:id
end
collection do
get 'sold' #=> products/sold
end
end
You can also nest resource routes within other resource routes:
# routes.rb
resources :products do
resources :comments #=> RESTful routes patterned as products/:product_id/comments/:id/:action
resources :sales do
get 'recent', :on => :collection
end
end
Another handy feature is named routing. The following route is not resourceful:
# routes.rb
match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase # Creates route path akin to purchase_path(:id)
Namespaced routes can be very helpful for organization and readability:
# routes.rb
namespace :admin do
resources :products #=> RESTful routes patterned as admin/products/:product_id/:action
end
So, basically, there's a route for everything you want to do, whether it's RESTful/resourceful or not. But yes, you need to write a route for every action you want exposed to your app.
Using the routes.rb file, you can create routes or pattern matching for routes, as well as parameterized routes, and nested routes. You should read more about this here.
You can also give routes their own method name such as my_new_route_path. If you really wanted to, you could just hardcode routes into your HTML. Please don't do this.
Every controller action needs routes that map to it.

Custom actions in rails controller with restful actions?

I'm having some trouble with using creating my own actions inside a controller I generated using the scaffold.
I understand everything maps to the restful actions but I'm building a user controller where users can login/logout, etc but when I created the action and declared it in the routes.rb I get this error when I visit users/login
Couldn't find User with id=login
It tries to use login as a ID parameter instead of using it as an action.
Routes.rb
match 'users/login' => 'users#login'
I think I'm doing something wrong with the routes so if anybody could help me that would be great.
Thanks
I assume your routes.rb looks like this:
resources :users
match 'users/login' => 'users#login'
The problem is that Rails uses the first route that matches. From the documentation:
Rails routes are matched in the order they are specified, so if you have a resources :photos above a get 'photos/poll' the show action’s route for the resources line will be matched before the get line. To fix this, move the get line above the resources line so that it is matched first.
So either define your custom route before resources :users:
match 'users/login' => 'users#login'
resources :users
…or use this syntax for adding more RESTful actions:
resources :users do
collection do
match 'login'
end
end
To see the existing routes (and their order) run rake routes from the command line.

My routes has resources :home, but rspec is saying routes not defined?

My homecontroller has:
def about()
end
And I have a rspec test that does GET 'about' and it fails saying that there is no route that matches.
doesn't this map all actions in the controller:
resources :home
or do I have to explicitly state each action in the home controller?
resources :home sets up the default RESTful routes - index, show, new, create, edit, update, and destroy. Any additional routes have to be specified. It looks like you're adding a simple collection route, so you'd specify it like this:
resources :home
collection do
get 'about'
end
end
This will give your the route '/home/about'. I assume this is Rails 3. If you're in Rails 2.x, do it like so:
map.resources :home, :collection => {:about => :get}
And from the command line, you can always see what routes you have available with this command:
rake routes
I hope this helps!
EDIT: If you want a default route, you can add this:
match ':controller(/:action(/:id))'
This is a default route that will match any generic requests.
FULL ARTICLE: Routing in Rails 3 is its own beast. There have been a lot of questions about it lately, so I've created a very detailed article with code samples to help others:
Routing in Ruby on Rails 3
I created a companion Rails 3 app that can be downloaded to play around with, as well:
https://github.com/kconrails/rails3_routing
If you have any questions, please hit up my site and ask. Thanks!
resources will give you the 7 CRUD methods for a controller, if you want additional actions, you need to do something like the following:
resources :homes do
collection do
match "about" => "homes#about", :as => "about"
end
end
Then you'll also have an additional about_homes_path/url helper available.

Resources