This might be a tough one
I have a site which is using a polymorphic comments model.
Lets say the first model is library, and the second is book
so we have, library/1/book/63/
how do I route it so comments are then library/1/book/63/comments/1 ?
Thanks,
Elliot
update: looking for code for routes.rb file
You just nest them:
map.resources :libraries do |library|
library.resources :books do |book|
book.resources :comments
end
end
It may be confusing, but the polymorphic aspect of the data model is independent of the routes.
To call them via named routes, for a comment you'll need to provide a library and a book, even if it's unambiguous.
map.resources :libraries do |library|
library.resources :books, :has_many=>[:comments]
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 have a resource Library and a resource Books. A library can have lots of books, obviously. Something like Library.first.books works perfectly.
In my routes.rb file I've got:
resources :libraries
resources :books
What I'd really like to be able to do is request something like /library/3/books and get all of the books in the library with an id of three. I tried this:
resources :libraries, :shallow => true do
resources :books
end
resources :books
But when I request /library/3/books I get all of the books, not just library three's books. Is there a built-in/easy way to make this happen?
/library goes to index
/library/3 goes to show
/library/3/books goes to books with params[:id] = 3. You must render #books = Library.find(3).books.
I suggest you to build another model as a relationship model.
then use :
has_many :book, through: :somemodel
it works like tagging http://railscasts.com/episodes/382-tagging
In this way you do not need to worry about the nested routes.
Say I have a User that has_one ContactInfo.
An unrestful way to edit the contact_info would be to do this all through a single controller with a route of:
myapp.com/users/15/edit_contact_info
A more restful way would be to use two controllers, and route it like this:
myapp.com/users/15/contact_infos/23/edit
However, I don't like this, as the route includes the contact_info_id, which isn't really necessary for identifying the correct contact_info to update. Additionally, the contact_info_id is a confusing number for a user to see. (They may know their own user id, but the contact_info_id will seem like an arbitrary number).
Is there any way to RESTfully route like below:
myapp.com/users/15/contact_infos/edit
or something similar? Is this a bad idea?
resources :users do
get "contact_info/edit" => 'users#edit_contact_info'
end
I'd used a plural route, instead of a singular route. With the singular route, I get myapp.com/users/15/contact_info/edit.
Had:
resources :users do
resources :contact_infos
end
Changed to
resources :users do
resource :contact_info
end
I have a CRUD resource defined in my routes.rb file: resource :user.
I'm adding a new controller method for the user called search_places, which is performed on the user to find other users with the same places. I'm adding a route it.
Right now, I have:
post '/user/search_place', which isn't very DRY. I'm new to Rails and I was reading the Rails routing documentation and figured that I could possibly use
resource :user do
collection do
post 'search_place'
end
end
Is this considered good practice? I know this works (it passes my rspec route test), but is that how its best done?
Thank you,
When you add second don't need of first.
Add this:
resources :user do
collection do
post 'search_place'
end
end
Remove this:
resources :user
That makes DRY :)
Suggestion: Resources name should be defined in plural if u follow rails convention. (i.e) resources :users
Okay, so here's an example scenario. There is a student resource resources :students, and students has and belongs to many collections: resources :clubs, resources :majors, etc.
So we can set up our routes easily enough...
resources :clubs do
resources :students
end
resources :majors do
resources :students
end
resources :students do
resources :clubs
resources :majors
end
which generates us a bunch of standard RESTful routes
/clubs
/clubs/:id
/clubs/:club_id/students
/clubs/:club_id/students/:id
/majors
/majors/:id
/majors/:major_id/students
/majors/:major_id/students/:id
/students
/students/:id
/students/:student_id/clubs
/students/:student_id/clubs/:id
/students/:student_id/majors
/students/:student_id/majors/:id
So here's my question. With REST semantics, how would one delete a major for a student?
Browsing students under a major /majors/:major_id/students/:id would show that student in the specific major's 'collection'. But the route for deleting an :id, points to StudentsController#destroy, which would delete the student completely. Whoops! So maybe we go the other way, and perform DELETE on the resource at /students/:student_id/majors/:id and well now UnderwaterBasketweaving is now no longer offered at this school...Whoops!
Now granted, we could set the destroy method of ClubsController, MajorsController, or StudentsController to look for club_id, or major_id, or student_id, but lets say we also down the road want to add Fraternities and GraduatingClasses, etc. Each class would start to be comprised of huge switch conditionals looking to see what param was present... and then find the collection of either the top resource and remove the bottom resource, or vise versa. The Models themselves should decide whether they delete themselves if they have no more association records... 'Destroy' on that resource has become really a misnomer...
Is there an easier way to do this? Even popular restful rails plugins like make_resourceful or resource_controller would blow away UnderwaterBasketweaving when removing it from Joe's Majors or completely delete JohnDoe when removing him from the major UnderwaterBasketweaving. It would seem there's a potential for looking at the association to understand the desired effects of the semantics and what 'destroy' should do.
Then again, am I looking at this all wrong? Is it not UnderwaterBasketweaving -> Joe but UnderwaterBasketweaving+Joe as a single resource and what we're deleting is truly not Joe, nor UnderwaterBasketweaving, but the resource representing the combination? However, that's not easy when the controllers are Students and Majors, that in effect represent resources of the same name (MVC has really become RV...in the 'convention' approach and not developing Controllers that may have no bearing on a Model name, or the path to reach it) So you'd be deleting a Major or a Student; pick your poison...
How can I avoid managing conditionals across an infinite graph of associated resources where delete really isn't the intent when the delete is desired to be in context of a collection and not pertaining to its singularity...?
...major.student.delete... Is there a way for 'student' ActiveRecord object to know it was sent a 'delete' message in a method chain beginning with the 'major' AR object ?
Well the standard RESTful aproach is to use has_many :through and generate a cotroller for the association resource. Naming association resources is always difficult, but I'll attempt for this example.
resources :majors do
resources :studies
resources :students
end
resources :students do
resources :studies
resources :majors
end
The models would be of course:
class Major < ActiverRecord::Base
has_many :studies
has_many :students, :through => :studies
end
etc. (comment if you want me to elaborate)
Then for a student you wouldn't DELETE it's associated #student.major but his #student.studies.where :major => #major.