Subdomain for nested resources in Rails - ruby-on-rails

My rails app is set to use subdomains as described in this RailsCast:
http://railscasts.com/episodes/221-subdomains-in-rails-3
However, right now, paths render like this:
http://organization.domain.com/organizations/1/edit
I have the controllers set up to choose the organization based on the subdomain already, so I'm wondering if there's a way to strip out the /organizations/:id portion of the paths, such that:
link_to edit_organization(#organization)
goes to http://organization.domain/edit, instead of http://organization.domain/organizations/:id/edit
Since there's going to be many nested resources within organizations (people, donations, etc), it's important that URL's don't end up incredibly long, and that the path generation method remains pretty straightforward.
Is there a way to do this?

You could use a route like:
resource :organization, :path => ""
The will cut down your url to 'http://organization.domain/:id/edit`.
Getting rid of the :id is tricky, and I dont think it can be done directly. What I would do is something like:
resource :organization, :path => "", :only => [] do
match "index", :via => :get
match "new", :via => :get
match "show", :via => :get, :constraints => {:subdomain => /[a-zA-Z]+/}
match "edit", :via => :get, :constraints => {:subdomain => /[a-zA-Z]+/}
match "update", :via => :put, :constraints => {:subdomain => /[a-zA-Z]+/}
match "create", :via => :post
end
Not very DRY, but I think it should work.

Related

RAILS: Rendering views from the same controller based on the route

I have two routes (defined in my config/routes.rb)
match 'compare' => 'front_office#search_by_id', :via => :get, :as => :front_office_compare
match 'full_report' => 'front_office#search_by_id', :via => :get, :as => :front_office_full_report
I would like to know how I can tell my controller to render the view based on my route, without adding a parameter on my URL.
Based on this Question&Answer I Managed to get the result I want with
match 'compare' => 'front_office#search_by_id', :via => :get, :as => :front_office_compare, :defaults => { :render => 'compare' }
match 'full_report' => 'front_office#search_by_id', :via => :get, :as => :front_office_full_report, :defaults => { :render => 'full_report' }
And in my controller I defined my action as:
def search_by_id
render :action => (params[:render] || "full_report")
end
But is this a Good Practice or is there a better way to do it?
Instead of creating different routes for each category you are making for simplifying you can write it like:
# config/routes.rb
get ":category", to: "front_office#search_by_id", as: 'front_office', constraints: {category: /(compare|full_report)/}
the above routes looks for /compare and /full_report and this will call search_by_id action in front_office controller.
then inside the controller do as follows:
def search_by_id
render params[:category]
end
params[:category] will hold the slug values which we passed through the URL

How can I redirect to a specific controller/action with similar routes?

My routes are redirecting to the same controller even when I specified different properties inside my routes.rb file.
These are my routes.
match ':clube_id' => 'clubes#show', :as => 'clean_cluble', via: [:get]
match ':project_id' => 'projects#show', :as => 'clean_project',via: [:get]
These are the links that I am using.
=link_to 'Project', :controller => "projects", :action => "show", :project_id=>'xxxxx'
=link_to 'Clube', :controller => "clubes", :action => "show", :id=>'cccc'
The link for projects works well, but the linl for clubes is redirecting to projects controller. that is the problem.
The URLs that I spect are:
http://host_name/project_name
http://host_name/clube_name
You didn't specify different properties, both routes look's identical for Rails. The match method expect any string(or id) in the ':clube_id' or ':project_id', for example:
host_name/soho_project or host_name/1
How is Rails can recognize for a which model it's related? It can be a Project or Club. I suggest add something like the anchor to a match method.
match 'club/:clube_id' => 'clubes#show', :as => 'clean_cluble', via: [:get]
match 'project/:project_id' => 'projects#show', :as => 'clean_project',via: [:get]
and helpers:
= link_to 'Project', clean_project_path(:project_id=>'xxxxx')
= link_to 'Clube', clean_cluble_path(:clube_id=>'cccc')
Read more about routes from the Rails guides.

Rails routing, matching short urls?

I'm having an issue where I've created a route I'm using to match short token like urls, like this:
myapp.com/a2c3b
I'm doing that by using a route like this:
match '/:id' => 'items#show', :as => "show_item", :via => :get, :constraints => { :id => /[a-z0-9]{5}/ }
But the issue is that now my other routes like /admin don't work because that also has 5 characters, how can I work around this, and have both kinds of routes work?
Put all of your routes that would match before this route in the file... that is...
match '/admin'....
match '/login'....
match '/:id' => 'items#show', :as => "show_item", :via => :get, :constraints => { :id => /[a-z0-9]{5}/ }

Converting routes for rails 3

This is a pretty silly question but I'm having some real trouble figuring out. I want to convert the following routes to make it compliant for Rails 3 (from 2.8.x):
map.with_options :controller => 'static_pages', :action => 'show' do |static_page|
static_page.faq 'faq', :id => 'faq'
static_page.about 'about', :id => 'about'
static_page.blog 'blog', :id => 'blog'
static_page.support 'support', :id => 'support'
static_page.privacy 'privacy', :id => 'privacy'
static_page.howitworks 'howitworks', :id => 'howitworks'
static_page.contact 'contact', :id => 'contact'
static_page.terms_and_conditions 'terms_and_conditions', :id => 'terms_and_conditions'
end
Any help would be much appreciated!
I think I would do it like this:
scope '/static_pages', :name_prefix => 'static_page', :to => 'static_pages#show' do
for page in %w{ faq about blog support privacy howitworks contact terms_and_conditions }
match page, :id => page
end
end
This is awesome, I just wrote an article about this a couple weeks ago:
Routing in Ruby on Rails 3
It goes over most aspects of the conversion, with a downloadable sample app. While I didn't cover the with_options conversion specifically, I can do a little of that here. Here's a short way:
scope :static_pages, :name_prefix => "static_page" do
match "/:action", :as => "action"
end
This matches all the routes you have above, and your named routes would look like this:
static_page_path(:faq)
static_page_path(:about)
...and so on. If you want your named routes to still look like static_page_faq_path then you can specify them one at at time, like so:
scope '/static_pages', :name_prefix => 'static_page' do
match '/faq', :to => 'static_pages#faq'
match '/about', :to => 'static_pages#about'
# fill in all the rest here
end
I hope this helps!

get, match and resources in routes.rb

I am new to Rails. I found it very strange when I use the resources in routes.rb, after I redirect the page to controller/index, it render the controller/show .
I know GET controller/action is same as match "controller/action", :to => "controller/action"
I think the strange thing happens to me about the redirect, is similar to the GET and Match.
so I wonder what exactly the resources mean, can I use some simple match do the same thing?
resources is a shortcut for generating seven routes needed for a REST interface.
resources :widgets is equivalent to writing
get "widgets" => "widgets#index", :as => 'widgets'
get "widgets/:id" => "widgets#show", :as => 'widget'
get "widgets/new" => "widgets#new", :as => 'new_widget'
post "widgets" => "widgets#create", :as => 'widgets'
get "widgets/:id/edit" => "widgets#edit", :as => 'edit_widget'
patch "widgets/:id" => "widgets#update", :as => 'widget'
put "widgets/:id" => "widgets#update", :as => 'widget'
delete "widgets/:id" => "widgets#destroy", :as => 'widget'
it just saves you the trouble.
By the way, get is not exactly the same as match. get, post, put and delete are shortcuts for limiting the route to a single HTTP verb. The two route definitions below are equivalent.
match 'foo' => 'controller#action', :method => :get
get 'foo' => 'controller#action'

Resources