RESTful nested controller in has_one relationship - ruby-on-rails

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

Related

How to set child index path without specific parent id in Rails?

I have route.rb like this:
resources :companies do
resources :company_jobs
end
And rails routes:
company_company_jobs GET /companies/:company_id/company_jobs(.:format) company_jobs#index
I need to add a link to show all company_jobs model without specific company_id like this:
Any one how can I config route to do this? Thank you so much!
What your routing implies is that you want all company_jobs that belong to company identified by :id. Assuming that you have a model association set up between the two models, this would be referenced as <%= link_to company_company_jobs(#company) %> - rails will fill in the id for you.
If instead, you just want to include all jobs no matter which company, you could change your routes to:
resources :companies do
collection do
get :company_jobs
end
resources :company_jobs
end
This will create a new route companies_company_jobs_path company#company_jobs
For this route to work, you will need to add the following to companies_controller.rb
def company_jobs
end

Rails routes, using something other than model_id in resources route

I have some nested resources. Here's an example:
resources :contests do
resources :scoring_periods do
resources :entries
end
end
I'd ultimately like to have a URL that looks like the following:
/contests/1/scoring_periods/10/entries/new
The catch here is that the /10/ in scoring_periods is not the ScoringPeriod#id. It is instead another attribute named period_count in this case. I'd like to be able to reference the period_count in the URl instead of the ID as my system might have millions of IDs later and it's just not intuitive to list it there. The actual period_count number, makes a lot more sense to the users entering this contest.
Is there a way to munge the resources entry in routes.rb in order to allow me to reference scoring_periods by an attribute other than :scoring_period_id ?
Something like this should work:
resources :contests do
scope path: '/scoring_periods/:period_count/' do
resources :entries
end
end

Rails routes, how to specify this member proper

I currently have some routes that look like the following:
resources :contests do
member do
get :enter
end
end
This allows me to do an HTTP GET on a URL that looks like /contests/5/enter. Now, a user can go in, fill in some forms, and be able to submit an entry to the contest. So I'd also like to be able to POST to this URL. I tried doing the following:
resources :contests do
member do
get :enter
post :enter
end
end
This posts to the same controller#action as the GET member that I have specified, so it's not really intuitive. I'd like to be able to direct it to a separate action if at all possible. What's the best way of doing that? I am using Ruby on Rails 4 beta currently.
** UPDATE **
I tried the following but I get an ArgumentError exception when I start the server:
resources :contests do
member do
get :enter
post :enter => "contests#create_entry"
end
end
You can do something like this:
resources :contests do
member do
get :enter
post '/enter', to: "contests#create_entry", as: "create_entry"
end
end
However i agree with Ola Tuvesson, you should definitely create a new controller and routes for entries, even though you may not have a model, similiar to how you often have a session controller for login and logout. Something like this:
resources :contests do
resources :entries, only: [:new, :create]
end
You can specify the controller/action you want to point a route at.
get :enter => "controller#get_enter"
post :enter => "controller#post_enter"
I would suggest you make the entries for a contest a child model of contests. That would give you all the CRUD methods on entries and your routes would simply be:
resources :contests do
resources :entries
end
A GET of /contests/5/entries/new will give you the form for adding an entry and when this POSTs to /contests/5/entries it would create a new entry. It also makes it easy to list all entries for a competition etc. You can easily create the controller, model and the associated views with the scaffold generator, for example:
rails g scaffold Entry contest:references name:string email:string
The references column type tells the generator to link Contests to Entries in a one to many relationship. Job done.
Edit:
If you still want to rename your routes, here's how:
http://guides.rubyonrails.org/routing.html#overriding-the-named-helpers
HTH

Should routes be nested for associations?

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.

Adding Rails Individual Route

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

Resources