Having difficulty defining Rails route - ruby-on-rails

I'm new to rails and I'm trying to create a new route to perform an action.
Currently I have the following defined in my routes
match 'books/scrape_data' => 'books#scrape_data', :via => :get
and the following action
def scrape_data
#books = Book.all
#books.each do |book|
# do stuff
end
redirect_to :action => 'list'
end
But the route seems to go to the show action with :id 'scrape_data'.
Can anyone point my in the right direction?

It sounds like you must also have a route definition such as resources :books that appears before the route you listed in your question. Since routes are parsed top-down, the books#show route is intercepting your route and bucketing scrape_data into the id. Run bundle exec rake routes to see the order of the routes defined.
The easy fix is to move your route up above resources :books. But it'd actually be more correct to get rid of your custom route and add it to the resources block like this:
resources :books do
get 'scrape_data', on: :collection
end
After this, do another bundle exec rake routes and see if that's what you wanted.

Excuse the "answer", but I don't have the rep to comment.
My go to resource for all things routing related is Routing from the outside in
Run bundle exec rake routes to see your routes and how they're nested. Then you'll see whether your params are matching up (common mistake with nested routes).

You can also view all of your routes by going to:
http://localhost:3000/rails/info/routes
which can be pretty helpful instead of having to kill your server and use the console.

Related

Rails custom routes

I have created an extra route called 'add' in my Groups controller.
get 'groups/add', to: 'groups#add'
My goal is to have the following link http://localhost:3000/groups/4/add
I thought about doing this nested route
resources :groups do
get 'groups/add', to: 'groups#add'
end
However when I run rake routes it is not listed. I have never really worked much with 'custom' routes before. I typically make due with the ones generated by a scaffold. How can I achieve this?
The following nested route has fixed my issue:
resources :groups do
get 'add', on: :member
end

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

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.

How do you check the URL Helpers for a Model Resource in Rails?

I'm currently following the Shovell tutorial in the Simply Rails 2 book. On page 168, it mentions URL Helpers for the Story Resource:
stories_path /stories
new_story_path /stories/new
story_path(#story) /stories/1
edit_story_path(#story) /stories/1/edit
The above is then used in the controller:
def create
#story = Story.new(params[:story])
#story.save
redirect_to stories_path
end
My routes.rb:
ActionController::Routing::Routes.draw do |map|
map.resources :stories
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
It looks like stories_path is the url name to /stories. Is that explicitly defined somewhere within my app, I can't seem to grep for that keyword. If not, is there a way that I can check the mapping above from the Rails console or somewhere else? In Django, url names are usually explicitly defined in urls.py, I just can't figure out how the above is being generated. Any documentation and pointers will help.
To get a list of the mapped routes:
rake routes
What map.resources :stories is doing is mapping your RESTful actions (index, show, edit etc.) from the stories_controller.rb to named routes that you can then use for simplicity.
routes.rb includes helpful tips on defining custom routes and it may be worth spending a little bit of time looking at resources in the API to get a better understanding:
http://api.rubyonrails.org/classes/ActionController/Resources.html#M000522
I think checking out the Rails Guides on Routing will help you a lot to understand what's going on
In short, by using the
map.resources :stories
the Router will automatically generate some useful (and RESTful) routes. Their path will take the model name (remember in Rails there is the Convention over Configuration motto), and, by default, will generate routes for all the REST actions.
This routes are available through your controller, views, etc.
If you want to check out which routes are generated from your mappings, you can use the "rake routes" command.
Now, given that, you can also write explicit URLs on your routes.rb file for actions or events that don't quite comply with the REST paradigm.
For that, you can use
map.connect "/some_kind_of_address", :controller => :pages, :action => "something_else"
Or
map.home "/home", :controller => :pages, :action => "home"
The last one will gave you both home_path and home_url routes you can use in your code.

Resources