I've been digging around on subdomains in Rails for a couple days and haven't found a good explanation of this yet...
I have a rails app which has a blog integrated into it, and I'd like to put that blog on a subdomain. Ie. blog.myapp.com.
Now, within the blog I want the user to be able to view posts, blog.myapp.com/posts/123. However, if the user were to click to any other resources on the site, say videos for example, I'd like them to be redirected back to root, ie. www.myapp.com/videos/123. I don't want blog.myapp.com/videos... to cause a routing error, I just want it to redirect.
Basically, I'm looking for the simplest way to setup a subdomain and specify that certain controllers use that subdomain and the others don't. Ideally I'd even like the controller layer to handle redirection both ways, so that in views I could link back and forth to things just using helpers like post_path(123) and video_path(123) and that the subdomain would automatically be used or not used based on which controller was serving the view.
I tried putting all the controllers in a constraints block, ie:
constraints :subdomain => 'www' do
resources :sessions
resources :users
resources :videos
root :to => 'home#show'
end
constraints :subdomain => 'nexturb' do
resources :posts
root :to => "posts#index"
end
root :to => 'home#show'
However this doesn't seem to work well, I've especially had trouble with getting redirection between links to work very consistently.
I'm pretty sure other people must have run into this issue in the past, but I can't seem to find a good example of this situation in writing. What's the best way to handle this?
With help from here, here, and here... I finally figured this out:
constraints :subdomain => 'blog' do
scope '', :subdomain => 'blog' do
resources :posts
end
root :to => 'posts#index'
end
This causes the posts_path helper to correctly send visitors to the subdomain.
I used #Andrew's answer. Some extra tips:
This railscast suggests using lvh.me to make subdomains work on localhost by visiting urls like blog.lvh.me:3000 or lvh.me:3000
Add the routes available in Andrew's answer
You may then have to add this to config/development.rb:
config.hosts += ["lvh.me", "blog.lvh.me"]
Related
I am someone who has always liked sinatra better than rails, and has never had to do a large enough scale project that rails was required (all the sources I have read say that rails is better for larger scale projects) and now I do have to do a large scale project. I have gotten very confused with the url structure of rails. What I am trying to do is the rails equivalent of this:
get "/" do
erb :index
end
get "/home" do
erb :dashboard
end
get "/home/profile" do
erb :profile
end
get "/home/friends" do
erb :friends
end
In the first one I understand that I should put in app/routes.rb I should put root home#index and in the home controller I should put def index end.
In the second one, I understand that I should do the same except replacing index with home.
But for the third and forth ones I have no idea what to do.
Also, is the a RESTful way to do the first two?
You probably want something like this
root 'home#index'
get 'home' => 'home#dashboard'
get 'home/profile' => 'home#profile'
get 'home/friends' => 'home#friends'
remember to use the command rake routes to see all your routes, where they lead and what their names are (if they have any)
I never understood what RESTful means, so someone else will have to answer that part of your question.
K M Rakibul Islam has shown you what can be called a "resourceful" way to do routes (because it uses the keyword resources) but it looks like you're just doing the static pages at this stage, so it's not necessary.
The simplest way to do routes is with this formula:
method url => controller::action, as: route_name
where method can be get, post, patch or delete so you can have different actions linked to the same URL depending on the method the request uses.
Putting a name on the route is optional, but it gives you a clean way to use the route in your views (route_name_path)
When you start making models then you'll find that using the resources keyword comes in handy. Read about it.
You can have this:
resources :home do
collection do
get :profile
end
collection do
get :friends
end
end
end
This will give you routes like this:
profile_home_index GET /home/profile(.:format) home#profile
friends_home_index GET /home/friends(.:format) home#friends
The standard way of declaring the root path:
root 'home#index'
And for the 2nd one, you have to do:
get 'home' => 'home#dashboard'
which will give you this route:
GET /home(.:format) home#dashboard
One route can be defined in many ways that works. But, Rails has conventions that should be followed while defining routes in your Rails app.
I would highly recommend you to take a look at the Rails Routing Guide
I came up with problem that to make good SEO there can't be underscores in links. I have project runing Ruby On Rails 3.
So I now wonder how it is posible to remove them and/or replace them with dashes.
I tried to search for this Q but there apeared just answers that are related to CSS. Like removing underscore from links.
Here is part of my routes file.
root :to => "home#index"
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
scope "(:locale)", :locale => /en|lv|ru/ do
resources :products,:waste_equipment,:sitemap,:energy, :energy_wood_machinery,:fuel_tanks, :soil_equipment,:soil, :tractors_and_loaders,:support_for_sport,:search,:location,:used_items,:admin_users,:conditions, :details,:projects,:knives,:messages, :mails, :photos,:emilianaserbatoi_products, :send_email_us,:subscribes, :home,:manufacturers, :location, :categories, :news, :manufacturer_products, :about_us,:contacts, :services, :partners
end
I wonder, that can be done using routes file or some gem is necessary?
Thanks!
You can do what you suggest in your comment, but you must not do it at once because you 'll end up with all your previous link invalidated and that is the SEO equivalent of shooting your leg.
you should:
add the new rules as an extra set of rules
log legacy link access
provide moved_permanently status code (301) for redirecting from old routes to new
a while after your logs are empty from legacy links remove them from google admin tools and update the routes
Sorry if my title isn't clear enough.
In my app I have a blogs resource. Now, normally this could turn out like "www.example.com/blogs/new", "www.example.com/blogs/the-internet-blog" etc. but what I want is to move the "blogs" from behind the .com to being a subdomain. ("blogs.example.com/new", "blogs.example.com/the-internet-blog").
Do I now really need to route all my actions basically manually or is there an option for a rest resource to make it aware of that tiny url logic change?
Yes, you can specify a subdomain in your Rails routes, using a :subdomain constraint as described in the Rails Routing Guide:
constraints :subdomain => "admin" do
resources :photos
end
And to construct links using subdomains, you can use the url_for extension described in this ASCIICast post:
Subdomains in Rails 3
Based on Stuart M's answer I got it to work now, I also was missing the important path-option.
These are my routes now for the blog logic:
constraints :subdomain => "blogs" do
resources :blogs, :path => "/"
end
I have a production Rails 2.3.5 website, and I'd like to the change the name of a model to something that will look much better in the URLs. I know the easy way to do this is in routes.rb like this:
map.resources :announcements, :as => :posts
However, I need to support the old name as well since we're production and can't have dead links. Just using ':as' isn't going to cut it.
I'm basically looking for a way to redirect so that:
http://mysite.com/announcements/23
redirects to
http://mysite.com/posts/23
It's probably possible to do this through Apache, but I can't seem to figure out the rewrite rules. I thought maybe routes.rb would be an easier method. Not having luck there either.
Thanks!
Depends on what we mean by "redirect" - it sounds like the most efficient route might be to take your posts controller and add redirects to announcements, and let the announcements controller handle the pages. So, in PostsController:
def index
redirect_to 'announcements#index'
end
and so forth. That gives you legacy support for old links for as long as you want it, and if there ever comes a time that you don't want it anymore you can just drop the whole Posts Controller.
I ended up finding a solution that works out pretty well.
I added the :as => :posts to my routes.rb, which makes all the link helpers create links to the new URLs. Then I figured out a mod_rewrite rule to handle redirects so there aren't any broken links out there on the internets. Here's what I added to my Apache config:
RewriteEngine On
RewriteRule ^/announcements(.*) /posts$1 [R=301,L]
How about adding the route two times. With :as option and without?
//routes.rb
map.resources :announcements
map.resources :announcements, :as => :posts
I am using Ruby on Rails 3. In my project I have many classes and some of those are stated in the routes.rb file like the following:
#routers.rb
resources :users
namespace "users" do
resources :profiles
...
end
With the above code I can access the following URLs:
<my_web_site>/users/1
<my_web_site>/users/1/edit
...
# and also
<my_web_site>/users/profiles/1
<my_web_site>/users/profiles/1/edit
...
What I would like to do is to redirect some URL requests to others URL but if in the routes.rb file I redirect all those, some controller actions will not work properly because also those requests are redirected (GET, POST, ...).
How can I solve this issue?
P.S.: I know that (maybe) my router statements are wrong, but at the moment I am looking for a easy solution too the problem. However suggestions about this matter are welcome.
Ok, looks like you want to set up a redirection that will only apply for to a given path and just one HTTP verb. This seems to be what you are looking for:
#routers.rb
resources :users
match "/users/profile/:id" => redirect("/profiles/%{id}"), :via => :get
namespace "users" do
resources :profiles
...
end
Based on this routes every GETrequest hitting /users/profile/1 will be redirected to /profiles/1 while any POST, PUT or DELETE requests won't be suffering the redirection.
The :via param will execure the redirection only if the request method math the given value. It also accepts an array of verbs so, for example, you can redirect :via => [:post, :put]
If you add more detailed information about the specific redirections that you need we can create a better example.
Check this great article, it will help you:
routing
you can define urls that you need to redirect to in routes.rb.
For example:match 'some_url/:id' => redirect_to('/path_to_redirect')