If I were to have for example a 'languages' model view and controller. Then within that I were to have tracks, and then within that I were to have lessons. How would I go about making a route for the lesson, would it be:
/languages/:language_id/tracks/:track_id/lessons/:lesson_id
Doing this would mean nesting them, something which is advised against.
My question is how would I create a route that would suit this and still convey to Rails the parent and it's identifier?
Yes you are right. You shouldn't nest your route no more than 1 level deep. However to get the approach you are after by using shallow nesting as highlighted here: Section 3.7.4. Primary purpose for this is to generate the collection actions scoped under the parent, so as to get a sense of the hierarchy. So you could do:
resources :languages, shallow: true do
resources :tracks do
resources :lessons
end
end
Related
So this may be more of a convention question, but im writing a todo app to learn how to use rails as an API (Im somewhat intermediate with using rails normally) but this time im using it with React for the front end.
Im making a simple todo app, two models in particular being "Lists" and "ListItems". Lists has_many ListItems of course, and a ListItem belongs_to a List.
So naturally I have the routes set up like so:
resources :lists do
resources :list_items
end
Giving me routes similar to: /api/v1/lists/:list_id/list_items etc.., However I saw some people doing a similar app set it up like:
namespace :v1 do
resources :list_items
resources :lists
end
Which confuses me because how would you handle passing the actual "List" params to the route, when the route itself would not have a List_id param?
Or would this more be used for a join table somehow..but you would still have to populate the List_id regardless when creating a list_item for a specific list correct?
Is there a preferred way of doing this as far as routing goes? (And I suppose creating tables?) Since a has_many_through seems not really necessary in this case?
Unless there is more to the story, you are doing it the more conventional way. I suggest your can safely disregard that not-nested approach. The only enhancement I suggest is using shallow: true, like:
namespace :api do
namespace :v1 do
resources :lists do
resources :list_items, shallow: true
end
end
end
You can read more about shallow nesting in the guide.
I'm having a hard time conceptualizing the best way to set up the resources for this project.
Here are my current routes:
resources :customers do
resources :jobs
end
resources :jobs
resources :rooms
resources :memos
resources :appliances
resources :accessories
end
I took my structure from this question: Rails 3 routing: Avoiding Deep Nesting
My question(s) are as follows:
Am I doing this right?
If yes, what does this accomplish that nesting more than 1 level deep does not? I'm assuming it's just absolute paths for things like jobs/rooms/id, instead of customers/jobs/rooms/id - but I don't know if this is correct.
Any further education will be appreciated. Thanks!
Yes, you are doing it right. You could either nest the resources or not, it is up to you.
Nesting one more level usually "forces" you to find each resource.
Consider these routes:
resources :customers do
resources :jobs do
resources :rooms
end
end
Then you would have relative paths like /customers/1/jobs/2/rooms/3/show.This implies that the Room #3 belongs to Job #2 which belong to Customer #1.
In other words, you would end up for the show action of the RoomsController with 3 instances: #customer, #job and #room, all set by a SQL query.
But you already defined that a room belongs to a job and that a job belong to a room. So do you really have to run 3 SQL queries? No, which is why you avoid deeply nested routes (over 2~3 levels).
I have 3 resources that are structured in a hierarchy as follows:
house 1-* residents 1-* books
We know that its not great to have deeply nested routes, so we endeavour to have routes nested at most 1 resource deep. Defined something like:
resources :houses do
resources :residents
end
resources :residents do
resources :books
end
The problem is that we end up defining :residents as a resource that can be accessed without any nesting - as part of the definition of :books. Is there way to define :books as being nested in :residents, without inadvertently registering :residents as a top level route?
This can be accomplished by using scopes, in your case:
scope 'residents/:resident_id' do
resources :books
end
However, as I mentioned in the comment, this practice can end up confusing users who expect URLs to behave in a certain way (deleting the last bit takes them up a level).
I have a one-to-many association between User and Occupation (a user has_many :occupations). In the routes file, I did:
resources :users do
resources :occupations
end
to nest the occupations routes inside the users. Playing around with AJAX requests, I realized it's easier for me to not have the occupations route nested, like this:
resources :users
resources :occupations
My question is, do I lose (performance, functionality) in any way by not having the routes nested?
Update: Aside from losing the users/1/occupations routing. I know that I won't get that if I don't nest the routes.
I wouldn't worry about the performance (if anything, the nested routes might be slightly slower) and just design the routes that make the most sense for your application.
Say I have this setup:
My model is 'content', and I want to use this model in 2 controllers.
blog_controller.rb
article_controller.rb
My 'content' model has a property 'content_type' which tells me if this content is a 'blog' or a 'article'.
This seems to prevent me from doing:
resources :article
resources :blog
right? since the models are different? or can I still do this?
You can still do it.
In your routes file, the resources method is, by default, looking for a controller of the same name that you pass it. So regardless of what the model's name is, if you have a controller named blog_controller you can do resources :blog
In classic SO fashion, instead of answering your question I'm going to criticism your implementation ;-)
I think the root of your problem is that you want a single table for content, with code shared between articles and blogs. In rails, the way to do that is called "Single Table Inheritance".