Rails Remove Certain routes - ruby-on-rails

I have a rails app and I have some custom routes. I have a database called Reports. In my routes.rb i have match '/new' => 'reports#new' however the problem is that /new goes to the right place, but /reports/new is also still active. Is there a way to "deactivate" the standard /reports/new so that only /new works?

If you're only interested in disabling one action except may be more appropriate than only. It works in a similar way.
... :except => :new
http://guides.rubyonrails.org/routing.html#restricting-the-routes-created

Sure, there is. You can use the only option as in (for example):
resources :reports, :only => [:create, :edit, :update]
which defines routes only for the specified actions (run rake routes to see all the routes)
(so it doesn't remove routes, it just does not generate them)
Edit: Plus, of course, there's also the except option (also see #Andy Gaskell's anwers) - which generates all routes except for the given actions, see the docs.

Related

Using Rails 2.3.8 I am trying to create a new view for a child object

So I have a pretty basic issue I guess. I'm using Ruby 1.8.7 and Rail 2.3.8 b/c the web host is pretty out of date. Anyways, I have an Event which has RSVPs associated with it. I have an administrator that I want to have access to a better view (more information_ of the RSVPs for the event.
The RSVP currently indexes like normal /events/1/rsvps which I get to using event_rsvps_path(event) and use an index.html.erb file. I made a adminindex.html.erb and put an adminindex in the rsvp controller. But now I don't know how to create a link to that adminindex.html.erb file.
The usual methods like link_to :controller=>'rsvps', :action=>'adminindex' don't work for obvious reasons to me.
The Routes file has map.resources :rsvps, :except => :update
Can someone tell me how to link the index to the adminindex file if the admin is signed in?
The problem is in your routes.rb file. Creating a resource only makes routes for the 7 RESTful actions (index, show, new, create, edit, update, destroy)
Since you have a custom action, you have to add a custom route for it. Try this:
map.resources :rsvps, :except => :update, :collection => { :adminindex => :get }
Run rake routes to see if it made the route correctly.

Rails routing get and match

When I'm generating controller with methods in routes I have something like this:
get "vehicle_manufacturers/show"
Is it a good practice that after that I will write such code:
match 'vehicle_manufacturers/:id/' => 'vehicle_manufacturers#show', :as => :vehiclemanufacturers
Or, is there another way of writing this code so that will work properly?
It's best practice to follow Rails conventions for naming and routing to your actions. This lets you say:
resources :vehicle_manufacturers
This will automatically create routes for index, new, create, show, edit, update, and delete with the appropriate HTTP methods and helper names. Assuming it corresponds to a VehicleManufacturer object that conforms to ActiveModel conventions (like ActiveRecord, Mongoid, etc.), url_for will automatically Do The Right Thing™, letting you use forms and redirects and such with no extra routing-related work.
It's pretty common that you might only want a subset of these methods. That's fine too:
resources :vehicle_manufacturers, :only => [:index, :show]
You want to support additional methods outside the normal CRUD methods. Go for it:
resources :vehicle_manufacturers, :only => [:index, :show] do
get :stock_price, :on => :member
end
This would add a route named stock_price_vehicle_manufacturer mapping to /vehicle_manufacturers/:id/stock_price. Although, strictly speaking, I might consider a stock price to be a sub-resource...
The point is, try to use resources as the basis of your routing. It makes everything easier.

Rails routes based on a value in a column

Rails 3.1. I have a table places. It has a column called type which has value such as cafe, restaurant, etc. Just one value in each row.
In my routes, I define the resources as:
resources :places
The URL is:
http://domain.com/places/123?type=cafe
I always have the type appended in my URLs because I use that to determine which navigation menu to be highlighted.
Now, I want to create a friendlier URL. How can I create a URL that reads either of these:
1. http://domain.com/places/cafe/123
2. http://domain.com/cafe/123
Many thanks!
There are two types of routes - resourceful and non-resourceful. It sounds like you're trying to do a mix between the two. Unfortunately, resourceful route URLs can't be customized like you're trying to do via resources, but you can add additional routes to match the URLs you're trying to make.
To accomplish this, you'll have to create non-resourceful routes such as these:
resources :places, :only => [:create, :update, :destroy]
match 'places/:type/:id' => 'places#show'
match 'places/:type' => 'places#index'
match 'places/:type/new' => 'places#new'
match 'places/:type/edit' => 'places#edit'
You don't need to create special routes for create, update, and destroy (though you could). The user never really sees those anyway. Just include the place type as a parameter in your forms and delete links, and it will be available in the controller the same way that it would as if it were coming from the URL.
In the controller, access the type via params[:type].
Why don't you use the value stored in #place.type, where #place = Place.find params[:id], to determine which navigation to use?

Router for nested resources in a "not usual" Ruby on Rails way

I am using Ruby on Rails 3.0.7 and I am trying to set nested resource routing to make it to work in a "not regular" RoR way.
In my routes.rb file I have
resources :articles do
resources :categories, :only => [:index], :controller => 'articles/categories' # The related controller is Articles::CategoriesController
end
so that I can browse following URLs:
<my_site>/articles/1/categories
<my_site>/articles/2/categories
...
What I would to do is to access new, edit and show controller actions for categories by using the same articles/categories controller used for the nested resource stated above (that is, Articles::CategoriesController) and by accessing these URLs:
<my_site>/articles/categories/new
<my_site>/articles/categories/edit
<my_site>/articles/categories/1
<my_site>/articles/categories/2
...
How can I do that? How I must code the router?
Maybe I can do something by using the router collection method like this
resources :articles do
collection do
# match something here for the Articles::CategoriesController...
end
resources :categories, :only => [:index], :controller => 'articles/categories'
end
but I don't know how to do that.
I'm not real sure what you're trying to do with those routes, so I'm not quite sure how to answer your questions. If your intent is to be able to add a new category for a particular article, or edit all the categories for a particular article, you have to pass an ID for the article. If you're trying to create a new article and a new category all at once, you don't need category in the route, just the article and you can do something like form_for([#article,#category]) in your form and use the build method in your controller. If you can clarify, I might be able to help you further (in other words, it's not hard to construct those routes -- but it depends on what you want to do with them.

Do you have to mess with Rails's "routes.rb" file?

I never touch routes.rb beyond calling map.root to set a default route. I've always been content to use URLs of the form...
/controller/action/perhaps_an_id
and it works fine.
Does this make me a bad person? Am I missing out on something totally awesome?
What if I try to adopt RESTful design? Would that mean I have to edit routes.rb or could I continue to pleasantly ignore it?
(I tried to read up on this topic in The Rails Way but it was unbearable.)
If you generate your resources with the default scaffolding then it will even include the restful routing for you in routes.rb.
If you're not using the scaffolding then the reason that it's working is because of the default routes at the bottom by default:
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
I've been following that it's best practice to remove these for production applications and instead make sure that only the resources that need to be exposed are exposed. With Rails 2.2 you can even limit the RESTful methods from map.resources by:
map.resources :posts, :only => [:index, :show]
map.resources :comments, :except => [:edit]
There's also tons of cool things you can do with nested resources, named routes, etc. They have a lot of examples in the docs (http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=M000255&name=resources)
You may also want to make custom named routes for your marketing department (eg: mycoolsite.com/free-trial) that go off to specific controllers and actions, etc.
Ryan Bates has a series of screencasts that go over some of the neat things you can do with routes: http://railscasts.com/tags/14
Not having switched to RESTful design does not make you a bad person and if you feel no need to change keep writing your apps the 1.x way.
The majority of Rails developers has adopted REST and seems to be very happy about it. I don't think there is a need here to repeat all pro REST arguments.
You do need to add one line per resource to your routes file such as:
map.resources :posts
If you were to go RESTful, yes you would have to edit routes.rb and add your resources like,
map.resources :your_resource
or if you have nested resources,
map.resources :people do |person|
person.resources :ideas do |idea|
ideas.resources :bad_ones
end
end

Resources