Change Rails namespaced route to personalized params route - ruby-on-rails

TL;DR: I want to have username621/posts/title-of-post instead of member/posts/1
The changing of post id to post title was easy enough since I used the freindly_id gem to generate the slugs.
However, I am having difficulty routing to a personalized params route instead of the current namespaced route. Here is the current routing:
namespace :member do
resources :posts
end
I want to replace the member namespace to user's username. So if their username is user123, the route should be user123/posts/title-of-post.
I think that this is not very standard Rails routing and tried looking for similar questions with no results.

for more complicated routes.rb, add a path option
namespace :member, path: ":user_id" do
resources :posts
end
should get what you want, e.g. http://localhost:3000/621/posts/1
then we just have to add friendly_id to User and Post to have it become something like http://localhost:3000/username621/posts/title-of-post
however, you'll need to pore through the codebase for things like member_post_path(post) and change to member_post_path(post.user, post)

Try removing the namespace and adding path option:
resources :posts, path: '/:username/posts/'
Then if you access /username621/posts/title-of-post in your controller you'll see params[:username] = 'username621'
If you have other paths of the form /something/posts add them above this route, otherwise they will be caught by :username.

Related

Rails 5 - how to add a prefix for a scaffold route?

I have generated a scaffold model car.
So if I want to create a new car, the URL looks like this: /cars/new. I need to pass another information to the URL and the easiest way is to simply add it as a parameter in the end, so the URL would look something like /cars/new?listing=123.
What I am trying to do is to get something like this in the URL: /l/123/cars/new (l = listings). Same for the other actions as well (eg. /l/123/cars/4/edit.
How do I need to modify the routes for such an example? listing is another model, and every listing has a car.
Thank you
AFAIK, you can't achieve this with resourceful way. You have to define non-resourceful routes to achieve what you want. For instance, the route for cars#new would be defined like below
get /:listing_id/:extra_param/cars/new, to: "cars#new"
I think you can use nested resources:
resources :listings do
resources :cars
end
It will generate routes like listings/:listing_id/cars/:id. If you do not have listings controller or you do not want to generate routes for it just use resources :listings, only: [] do ...

Rails routes - context for nested resource url

I'm trying to create a nested path for a show action of a nested resource
user.rb
has_many :fan_receives, as: :fanzone_owner, class_name: "FanActivity"
fan_activity.rb
belongs_to :fanzone_owner, polymorphic: true
In my routes.rb
match ":fanzone_owner_id/posts/:id", to: "fan_activities#show", via: :get
The path works, but the fanzone_owner_id could be anything. For an example,
example.com/1/fan_activities/2 works
example.com/2/fan_activities/2 also works
example.com/anythingatall/fan_activities/2 also works
I would like to make it so the fanzone_owner_id of the url must match the foreign key of the fan_activity, otherwise we redirect to 404.
Would I do this with validation check of the url in the controller? I'm not sure if this approach is correct
Based on the informations I would suggested to use nested routes.
resources :fanzone_owner do
resources :fan_receive
end
For that you should've also nested attributes ready, otherwise the above routing would make no sense at all. This tutorial could be helpful.
I figured out what was wrong. I just had to use the params from the url in the controller for the show action.
In the fan_activities_controller.rb
#user = User.find(params[:fanzone_owner_id])
#fan_activity = #user.fan_receives.find(params[:id])
If the user is not found or the user isn't the fanzone_owner, then it would be a 404.

Extract params fro url in rails

From the url below how can I extract the value 1?
`http://localhost:3000/category/products/1`
I tried params[:id] and params[:products][:id] but got nothing.
Did you make suitable change in your routes.rb file? You need to include something like
GET /category/products/:id , ...
to make it work with params[:id].
Routes
The direct answer to your question is to fix your routes.rb file
As per the Rails RESTful routing structure, you should be able to use a named scope to achieve this:
#config/routes.rb
scope 'category' do
resources :products
end
#/category/products/1 -> params[:id]
Nested
What I recommended above should fix your problem directly
However, I think you're trying to achieve nested resources. If this is the case, you should use something like this:
#config/routes.rb
resources :categories do
resources :products
end
This will allow you to do:
#categories/:id/products/:product_id

RESTful nested controller in has_one relationship

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

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