Giving a nested route an alias in Rails - ruby-on-rails

If I want to provide an alias for a controller, I can use map.resources :rants, :controller => 'blog_posts' yoursite.com/rants points to the blog_posts controller fine.
How do I give an alias to a nested resource, for example yoursite.com/users/5/rants ?

You may want to try:
map.resources :rants, :controller => 'blog_posts'
map.resources :users do |users|
users.resources :rants, :controller => 'blog_posts'
end
This will give you the yoursite.com/users/5/rants/ url that you are looking for and it will generate the handy methods (for example: users_rants_path(#user))
Hope this helps.

Related

Can't figure out how Rails route helper should look

I am working on an assignment which includes adding a feature to Typo.
rake routes shows:
admin_content /admin/content {:controller=>"admin/content", :action=>"index"}
/admin/content(/:action(/:id)) {:action=>nil, :id=>nil, :controller=>"admin/content"}
I need to create a route helper which matches the following RESTful route: /admin/content/edit/:id and an example of url is /admin/content/edit/1
But I can't figure out how to do it. I tried something like admin_content_path(edit,some_article) but it didn't work. (some_article is just an article object)
In routes.rb file:
# some other code
# Admin/XController
%w{advanced cache categories comments content profiles feedback general pages
resources sidebar textfilters themes trackbacks users settings tags redirects seo post_types }.each do |i|
match "/admin/#{i}", :to => "admin/#{i}#index", :format => false
match "/admin/#{i}(/:action(/:id))", :to => "admin/#{i}", :action => nil, :id => nil, :format => false
end
#some other code
Thanks a lot for your help!
If you are using RESTful routes, why not use the Rails default routes?
So your routes.rb would look like
namespace :admin do
resources :content
resources :advanced
resources :categories
resources :comments
...
<etc>
end
This does assume all your controllers are in the folder admin (but from your comment this seems to be the case.
If you do that, you can just use the standard route-helper: edit_admin_content_path.
If you want to do it manually, you should try adding a name to your route. E.g. as follows:
match "/admin/#{i}/:action(/:id)" => "admin/#{i}", :as => "admin_#{i}_with_action"
and then you should do something like
admin_content_with_action(:action => 'edit', :id => whatevvvva)
As a side-note: I really do not like the meta-programming in your config/routes.rb, if for whatever you really find that the default resources are not a right fit, I would advise to use methods instead (as explained here)
So for example in your config/routes.rb you would write:
def add_my_resource(resource_name)
match "/#{resource_name}", :to => "#{resource_name}#index", :format => false
match "/#{resource_name}(/:action(/:id))", :to => "#{resource_name}", :as => 'admin_#{resource_name}_with_action", :action => nil, :id => nil, :format => false
end
namespace :admin do
add_my_resource :content
add_my_resource :advanced
add_my_resource :categories
...
end
which imho is much more readable.
But my advice, unless you really-really need to avoid it, would be to use the standard resources since you do not seem to add anything special.
HTH.

Difference between :as option in Rails 2 and Rails3 routing?

In Rails 2.X we have:
map.resources :posts, :controller => 'posts', :as => 'articles'
This essentially creates an alias for our posts routes. For example, this sends "domain.com/articles/" to the posts controller index action.
In Rails3, however, the :as option behaves differently. For example:
resources :posts, :controller => 'posts', :as => 'articles'
sets a named route rather than an alias, and going to "domain.com/articles/" gives an error:
No route matches {:controller=>"posts"}
How do I get the old (Rails 2) :as behavior using the new (Rails 3) api?
PS: Please don't tell me to simply rename my controller. That's not an option for me.
From some cursory reading of the RoR guide on routing, I think you might need to try:
resources :articles, :controller => "posts"
(http://guides.rubyonrails.org/routing.html#specifying-a-controller-to-use)
You might also need to add :as => "articles", but that named helper might already be set up since you are adding :articles resources.
You can accomplish this same behavior using the path option:
resources :posts, :path => '/articles/'
Now for example /posts/new becomes /articles/new.

Rails routing help

I want the url of a user post to be like this:
example.com/users/username/post-name
How should I set this up?
Currently, the post model contains:
def to_param
name.parameterize
end
(to hyphenate the post name accordingly)
routes.rb contains:
map.resources :users
map.resources :posts
Preferably, I would like to say post_path(post) and this would generate the appropriate path for me by finding the post.user automatically.
What do I need to do to make this happen?
Also added
map.resources :users do |user|
user.resources :posts
end
One way more:
map.resources :users do |user|
user.connect ':name/:action', :controller => 'posts', :defaults => {:action => 'show'}
end
Available routes:
example.com/users/username/post-name
example.com/users/username/post-name/edit (any action)
Hi To make your application recognize routes like
example.com/users/username/post-name
you should add to your routes.rb
map.connect 'users/:username/:post', :controller => "users", :action => "test"
Then you can access params[:username] and params[:post] inside your controllers test action You should define it after map.resources :users but before map ':controller/:action/:id' but you must write your own helper then
That to_param looks okay, but the builtin helpers don't link to nested resources like you want, you'd have to use user_post_path(user, post). Ofcourse, you could write your own post_path helper method which does work the way you want.
def post_path(post)
url_for [post.user, post]
end

customize rails url with username

I want to copy the twitter profile page and have a url with a username "http://www.my-app.com/username" and while I can manually type this into the address bar and navigate to the profile page I can't link to the custom URL.
I think the problem is in the routes - here's the code in my routes.rb
map.connect '/:username', :controller => 'users', :action => 'show'
Also, I have Question and Answer models and I want to link to them with the customized URL like so:
http://www.my-app.com/username/question/answer/2210
There's nothing wrong with your route. Just remember to define it at the end, after defining all other routes. I would also recommend using RESTful routes and only if you want to have better looking URLs use named routes. Don't use map.connect. Here's some good reading about Rails routes.
Here's how this could look:
map.resources :questions, :path_prefix => '/:username' do |question|
question.resources :answers
end
map.resources :users
map.user '/:username', :controller => 'users', :action => 'show'
Just a draft you can extend.
To create urls you need to define to_param method for your user model (read here).
class User < ActiveRecord::Base
def to_param
username
end
end
I know this questions is old but it will help someone.
You could try the below. I've used it in a rails 4 project and all seems to be working great. The reason for the as: :admin is I also had a resources posts outside of this scope. It will add a admin to the helper calls e.g. admin_posts_path
scope ":username", module: 'admin', as: :admin do
get '', to: 'profiles#show'
resources :posts
end
I have used like this
In View part
portfolio.user.name,:id =>portfolio) %>
and in rout.rb
map.show_portfolio "portfolios/:username", :action => 'show_portfolio', :controller => 'portfolios'

Can controller names in RESTful routes be optional?

With a standard map.resource routing mechanics and several nested resources the resultant routes are unnecessarily long. Consider the following route:
site.org/users/pavelshved/blogs/blogging-horror/posts/12345
It's easy to create in routes.rb, and I'm sure it follows some kind of beneficial routing logic. But it's way too long and also seems like it's not intended to be human-readable.
A nice improvement would be to drop controller names, so it looks like:
site.org/pavelshved/blogging-horror/12345
Clear, simple, short. It may become ambiguous, but in my case I'm not going to name any user "users", for instance.
I tried setting :as => '', but it yields routes like this: site.org//pavelshved//blogging-horror//12345 when generating them by standard helpers.
Is there a way to map resources in such a way, that controller names become optional?
You're looking for the :path_prefix option for resources.
map.resources :users do |user|
user.resources :blogs do |blog|
blog.resources :posts, :path_prefix => '/:user_login/:blog_title/:id'
end
end
Will produce restful routes for all blogs of this form: site.org/pavelshved/bogging-horror/posts/1234. You'll need to go to a little extra effort to use the url helpers but nothing a wrapper of your own couldn't quickly fix.
The only way to get rid of the posts part of the url is with named routes, but those require some duplication to make restful. And you'll run into the same problems when trying to use route helpers.
The simplest way to get what you want would be to create a route in addition to your RESTful routes that acts as a shorthand:
map.short_blog ':user_id/:blog_id/:id', :controller => 'posts', :action => 'show'
You'll have to change the URL bits to work with how you're filtering the name of the user and the name of their blog. But then when you want to use the shorter URL you can use all the short_blog_* magic.
Straight out of the default routes.rb:
map.connect 'products/:id', :controller => 'catalog', :action => 'view'
You could write:
map.connect ':user_id/:blog_id/:id', :controller => 'posts', :action => 'show'
But be sure to include that in the very end of the file, or it will try to match every three levels deep url to it.
Try this
map.pavelshved '/pavelshved/', :controller => :users, :action => view or
map.pavelshved '/:id', :controller => :users, :action => show do | blogs|
blogs.bloging '/:id', :controller => :blogs, :action => show do | post|
post.posting '/:id', :controller => :posts, :action => show
end
end
I hope it work :)
Google "rails shallow routes" for information about this.

Resources