Nested Routes with has_one in rails - ruby-on-rails

G'day guys,
Having a bit of an issue with Rails routes, at the moment.
Have a top resource: /Customer/ which itself has only one /Quote/ resource
Quotes can have both first_resources and second_resources
which are collections of resources associated with the quotes
Building the route, though how do I nest multiple routes under a has_one route?
map.resources :customer, :has_one => :quote
how do I do?
quote.resources :first_resources
quote.resources :second_resources
by mapping them as sub-elements to the substructure?
Or would it be easier to manage the collection in a different way?

for this, I would nest inside of a block:
map.resources :customers do |customer|
customer.resource :quote do |quote|
quote.resources :first_resources
quote.resources :second_resources
end
end
alternative syntax:
map.resources :customers do |customer|
customer.resource :quote, :has_many => [:first_resources, :second_resources]
end
This would give you urls of
customers/:customer_id/quote/first_resources/:id
customers/:customer_id/quote
customers/:id
Or the way you provided I believe you would need to map plural quotes in order to be able to get to a specific quote if you don't want to nest
map.resources :customers, :has_one => :quote
map.resources :quotes, :has_many => [:first_resources, :second_resources]
that would give you urls of
customers/:customer_id/quote
customers/:id
quotes/:quote_id/first_resources/:id
I think the first one is what you are after. Hope this helps.
Resources: http://api.rubyonrails.org/classes/ActionController/Resources.html

map.resources :customers, :has_one => :quote
map.resource :quote, :has_many => :first_resources
map.resource :quote, :has_many => :second_resouces

Related

Rails3 nested routes with default base

From the example in rails guides, routes like:
resources :publishers do
resources :magazines do
resources :photos
end
end
Will lead to, URLs like:
/publishers/1/magazines/2/photos/3
I want to have slugs for publishers for example - Oxford
And avoid the first "/publishers" part
Making the URLs to something like:
/oxford/1/magazines/2/photos/3
What is the cleanest and best way to achieve this in Rails 3?
scope :path => ":publisher_slug", :as => "publisher" do
resources :magazines do
resources :photos
end
end
publisher_magazine_photo_path("oxford",2,3)

Can't add sub pages in a controller

Using RoR 2.3.8
This is my cities_controller.rb
class CitiesController < ApplicationController
def show
#city = City.find(params[:id])
...
end
def shops
...
end
def countries
...
end
end
Here's my routes.rb
map.resources :cities, :collection => {:shops => :get, :countries => :get}
The show url for each id is:
http://localhost/cities/1
I want to have some contents shops and countries for each associated id, which I want:
http://localhost/cities/1/shops
http://localhost/cities/1/countries
I can't get the pages showed in empty code in the first place. What have I done wrong?
Thanks.
The :collection option is for when you want to act on the whole collection - so your routes will show up as:
http://localhost/cities/shops
http://localhost/cities/countries
What you want is
map.resources :cities, :member => {:shops => :get, :countries => :get}
Reference: http://apidock.com/rails/ActionController/Resources/resources
Shops and Countries would probably not be methods in the controller but other models. you would want a Countries.rb and Shops.rb
You would then nest the resources like
resources :cities do
resources :shops
end
and you would need a belongs_to :city in the shops model and a has_many :shops in the cities model which would let you access cities/1/shops.... or something like that
However think about the way the data is structured, do countries really belong to cities (which nesting the resources would imply) or would countries contain cities. You would want cities belongs_to :country and so on...
This help?

Rails 3 issue with custom named resourceful route after update from rails 2

In the rails 2 version of my app I have this resource defined
map.resources :albums, :as => 'music', :has_many => :reviews
This gave me some standard routes:
album GET /music/:id(.:format) {:controller=>"albums", :action=>"show"}
new_album GET /music/new(.:format) {:controller=>"albums", :action=>"new"}
I also have a polymorphic association set up as follows:
class Album < ActiveRecord::Base
has_many :reviews, :as => :reviewable
end
class Review < ActiveRecord::Base
belongs_to :reviewable, :polymorphic => true
end
This meant I could create a link to my album resource through my review by using a polymorphic path
<%= review.reviewable.title, polymorphic_path(review.reviewable) %>
However, since upgrading to rails 3 I've changed my routes file to in order to comply with the new router:
resources :music, :controller => 'albums' do
resources :reviews
end
And although cleaner it breaks my polymorphic link, i.e.
<%= review.reviewable.title, polymorphic_path(review.reviewable) %>
I end up with the following error message
undefined method `album_path'
If I look in my rails 3 generated routes with "rake routes" i see
music GET /music/:id(.:format) {:action=>"show", :controller=>"albums"}
which is different to what was there before in the rails 2, i.e.
album GET /music/:id(.:format) {:controller=>"albums", :action=>"show"}
So my guess is that this is what's breaking things.
I'm a little unsure though as how to fix it without reverting back to the rails 2 routes which will be depreciated with rails 3.1. Any help would be appreciated. Thanks.
It turns out this was easy to fix. All I had to do was:
resources :albums, :path => 'music' do
resources :reviews
end

Route alias in Rails

I have a model stories in Rails 3.
I want to make an alias "books" for "stories" so I can have routes /books/192 instead of /stories/192, and also that all my generated links (e.g. link_to) point to books' routes instead of stories' routes.
How can I do that?
Thanks
resources :stories, :path => :books
If you want to rename the path AND helper methods, then you do:
resources :stories, :path => :books, :as => :books
See: Overriding the Named Helpers
That's why they made the path option on match which is also available on resources:
resources :stories, :path => "books"
Try something like this:
match 'books/:id' => 'books#show'
match 'books' => 'books#index'

Nested named routes in rails?

Lets say you have a two models with blog posts and comments set up like this:
class post
has_many :comments
and the routing was set up pretty much the same way:
map.resources :posts, :has_many => :comments
When I go to make a new comment it shows up as localhost::3000/postname/comments/new
What should you do in order to make the url read something like: localhost::3000/postname/shoutout ?
The reason I want to do this is because this particular page will have more than just a new comment form on it.
I have no trouble naming routes but I'm having trouble figuring out what to do with a nested one.
map.resources :posts, :has_many => :comments, :collection => {:shoutout => :get}
Key feature is :collection, which points of pairs: 'name' => 'method', and you need to implement this name in controller (and views)
The routes have nothing to do with the forms that are on the page, I'm not sure what the problem is?
If you want to have /postname/shoutout go to to CommentsController#new you'll need to map the route manually:
map.connect '/:post_id/shoutout', :controller => 'comments', :action => 'new'

Resources