We're developing a conference management app and most of the resources is nested resource of conference. Now, we decided to use subdomains for conference homepages and got trouble on refactoring resources.
Current url scheme is like:
/conferences/:id/speeches
/conferences/:id/manage
We want to move /conferences/:id part to subdomain and use resources like:
conferenceid.sitename.com/speeches
conferenceid.sitename.com/manage
Here are the current routes file:
https://github.com/kodgemisi/confdeck/blob/development/config/routes.rb#L17
What's the best way to make this transition? How can we prevent current url helpers?
first lets tweak your subdomain class. the following code should be enough
class Subdomain
def self.matches?(request)
request.subdomain.present? && request.subdomain != 'www'
end
end
then you should be able to call it in the routes with the following
constraints(Subdomain) do
resource :conference, path: "/" do
member do
get 'apply'
post 'apply' => "conferences#save_apply"
end
end
Then in your Controller you go like this:
Conference.find_by_slugged!(request.subdomain)
(i saw you use friendly id, so i think your subdomain is sluggged of the Conference.
Related
I have a Model (Show) in Rails that is accessed via a subdomain rather than a standard REST URL. In the file app/helpers/url_helper.rb I have the following method:
def show_url(show)
root_url(subdomain: show.subdomain)
end
In controllers, this works perfectly. I can test it with puts show_url(#show) and it outputs the subdomain of the show as expected: http://test.example.com. In integration tests, however, the method doesn't work, and the default one generated by rails is used instead. If I run puts show_url(#show) there, I just get http://example.com. How do I use this custom URL helper in my integration tests?
Edit:
routes.rb section regarding this subdomain stuff:
constraints(lambda do |request|
request.subdomain.present? && request.subdomain != 'www'
end) do
get '/' => 'shows#show', as: :show
get '/edit' => 'shows#edit', as: :edit_show
end
This is based loosely around a Railscast on subdomain matching.
Try defining its route without the default "show" action:
# config/routes.rb
resources :show, except: :show
Sounds a bit confusing since your model is called Show, but what it's doing is defining all the standard restful routes (index, new, create, edit, update, delete) except for "show", e.g.
Or another way:
resources :show, only: %w(index new create edit update delete)
I would really consider doing some refactoring and renaming the Show model.
I am trying to setup a subdomain for my site in rails. I followed to rails cast to do this.
http://railscasts.com/episodes/221-subdomains-in-rails-3?view=comments
I am having an issue. I want to state that for a specific static subdomain as a secondary homepage.
constraints(Subdomain) do
match '/' => 'static_pages#secondary_home'
end
root to: 'static_pages#home'
lib/subdomain.rb
class Subdomain
def self.matches?(request)
request.subdomain.present? && request.subdomain.eql? "secondaryhome"
end
end
so now I expect only secondaryhome.lvh.me:3000 to point to my secondary homepage. (lvh.me is and external domain that points to localhost) .However, any subdomain I have (for instance abc.lvh.me:3000) seems to be pointing to the secondary home, while i want it to default to my primary root. What should i do?
We've done the equivalent of this:
#config/routes.rb
constraints({ subdomain: "secondaryhome" }) do
match '/' => 'static_pages#secondary_home'
end
This sets a route for lvh.me:3000 with constraint { subdomain: "secondaryhome" } - only that should work
I have a subdomain widgets.mywebsite.com. The only thing the subdomain does is return json on a given route. How do I prevent people/crawlers accessing my site via the subdomain whilst still keeping the route available? I would be happy to simply redirect any requests that include this subdomain to mywebsite.com but can't work out how to do it.
constraints :subdomain => 'widgets' do
namespace :widgets, :path => nil, :format => 'json' do
match 'v1' => 'v1/widgets#index'
end
end
So it sounds like you want to reverse the logic in your routes - you want to constrain the bulk of your routes so that they only resolve when the subdomain isn't equal to widgets. That's opposed to the above example, where you're making a single route only available on the 'widgets' subdomain. This is pretty straightforward.
In your config/routes.rb you can define a class before the Application.routes.draw block
class NotWidgetsRequest
def matches?(request)
request.subdomain != 'widgets'
end
end
and then you can wrap all of your routes other than the v1/widgets#index route in a
constraints NotWidgetRequest.new do
...
end
block. This will prevent these routes from resolving on widgets.mywebsite.com
I dynamically create URLs of the form username.users.example.com:
bob.users.example.com
tim.users.example.com
scott.users.example.com
All of *.users.example.com requests should go to a particular controller/action. How do I specify this in routes.rb?
All other requests to www.example.com go to the normal list of routes in my routes.rb file.
UPDATE: I watch the railscast about subdomains and it showed the following bit of code which would seem to be exactly what I need (changed the controller and subdomain):
match '', to: 'my_controller#show', constraints: {subdomain: /.+\.users/}
The problem is it only matches the root URL. I need this to match EVERY possible URL with a *.users subdomain. So obviously I would put it at the top of my routes.rb file. But how do I specify a catch-all route? Is it simply '*'? Or '/*'?
I think, you just need to do the following :
create a class Subdomain in lib :
class Subdomain
def self.matches?(request)
request.subdomain.present? && request.host.include?('.users')
end
end
and in your routes :
constraints Subdomain do
match '', to: 'my_controller#show'
end
You can constraint route dynamically based on some specific criteria by creating a matches? method
Lets say we have to filter sub domain of URL
constraints Subdomain do
get '*path', to: 'users#show'
end
class Subdomain
def self.matches?(request)
(request.subdomain.present? && request.subdomain.start_with?('.users')
end
end
What we are doing here is checking for URL if it start with sub domain users then only hit users#show action. Your class must have mathes? method either class method or instance method. If you want to make it a instance method then do
constraints Subdomain.new do
get '*path', to: 'proxy#index'
end
you can achieve same thing using lambda as well like below.
Instead of writing class we can also use lambdas
get '*path', to: 'users#show', constraints: lambda{|request|request.env['SERVER_NAME'].match('.users')}
In a Rails 3.2 application I'm doing I want to create some views (and action handling) specific for mobile devices. So I have created a namespace called mobile.
namespace :mobile do
resources :sessions
resources :areas
end
For example if the user goes to the login page with a mobile I want to use the controller and views I make for that namespace.
So now I have two different ways to login:
new_mobile_session GET /mobile/sessions/new(.:format) mobile/sessions#new
and
new_session GET /sessions/new(.:format) sessions#new
But when a requests comes how could I add the "mobile" namespace to the request if it comes from mobile?
I.e. changing /sessions/new into /mobile/sessions/new
I am using Rack::MobileDetect but I don't know how to use the redirect_to for that purpose.
config.middleware.use Rack::MobileDetect, :redirect_to => '/mobile'
Or should I use a different approach?
Thanks.
You could use a constraint for that.
A Rails routing constraint either is class which responds to matches? or a lambda.
When a constraint is applied to a route, the route will only be considered if the constraint evaluates to true.
Consider this class
class MobileContraint
def matches? request
request.user_agent =~ /Mobile|webOS/
end
end
You can now use this class in the routes like this:
resources :sessions
resources :sessions, :controller=> 'mobile/sessions', :constraints => MobileConstraint.new