As a Rails NOOB, I started with a routes.rb of:
ActionController::Routing::Routes.draw do |map|
map.resources :events
map.connect 'affiliates/list', :controller => "affiliates", :action => "list"
map.connect 'affiliates/regenerate_thumb/:id', :controller => "affiliates", :action => "regenerate_thumb"
map.connect 'affiliates/state/:id.:format', :controller => "affiliates", :action => "find_by_state"
map.connect 'affiliates/getfeed', :controller => "affiliates", :action => "feed"
map.resources :affiliates, :has_many => :events
map.connect ":controller/:action"
map.connect '', :controller => "affiliates"
map.connect ":controller/:action/:id"
map.connect ":controller/:action/:id/:format"
end
and i'm trying to tighten it up. and I've gotten as far as:
ActionController::Routing::Routes.draw do |map|
map.resources :events, :only => "index"
map.resources :affiliates do |affiliates|
affiliates.resources :has_many => :events
affiliates.resources :collection => { :list => :get, :regenerate_thumb => "regenerate_thumb" }
end
# map.connect 'affiliates/regenerate_thumb/:id', :controller => "affiliates", :action => "regenerate_thumb"
map.connect 'affiliates/state/:id.:format', :controller => "affiliates", :action => "find_by_state"
map.connect 'affiliates/getfeed', :controller => "affiliates", :action => "feed"
map.root :affiliates
end
what is confusing to me is routes vs parameters.. For example, I realized that the only difference between list and index is HOW it is rendered, rather than WHAT is rendered.
Having a different action (as I do now) feels wrong but I can't figure out he right way.
Thanks
You can refactor it like this:
map.resources :events, :only => "index"
map.resources :affiliates, :has_many => :events, :collection => { :list => :get }, :member => { :regenerate_thumb => :get }
map.connect 'affiliates/state/:id.:format', :controller => "affiliates", :action => "find_by_state"
map.connect 'affiliates/getfeed', :controller => "affiliates", :action => "feed"
map.root :affiliates
The title says "serving different layouts". Where's the problem?
Related
I have the following code in a routes file which I haven't come across before, but need to get my head around it but I don't have a clue what's going on because I've only really used match ...
ActionController::Routing::Routes.draw do |map|
map.devise_for :users, :controllers => { :confirmations => 'confirmations' }
map.resources :sections, :only => [:index, :show]
def stories(parent)
parent.resources :stories, :only => [:index, :show], :collection => {:search => :get} do |story|
story.resources :videos, :only => [:index], :member => {:play => :get, :start_download => :get}
story.resources :images, :only => [:index], :member => {:start_download => :get}
story.resources :documents, :only => [:index], :member => {:start_download => :get}
story.resources :audios, :only => [:index], :member => {:play => :get, :start_download => :get}
end
end
stories(map)
map.namespace :manage do |client_admin|
client_admin.resources :stories do |story|
story.resources :meta_datas
story.resources :media_files, :collection => { :clone_metadata => :get }, :member => { :crop_thumbnail => :get } do |mf|
mf.resources :media_meta_datas
end
end
client_admin.resources :users, :only => [:new, :create, :index]
end
map.ftp_upload 'manage/stories/:story_id/ftp', :controller => 'manage/media_files', :action => 'ftp'
map.page ':page', :controller => 'pages', :action => 'show', :page => /terms/
map.contact '/contact', :controller => 'contact', :action => 'index'
map.resource :password_reminder
map.library_redirect '/library', :controller => 'media_files', :action => 'redirect'
map.library '/library/:media_type', :controller => 'media_files', :action => 'index'
map.press_kits '/corporate-information', :controller => 'stories', :action => 'press_kits'
map.resource :global_toolkit, :controller => 'global_toolkit', :as => 'global-toolkit', :only => 'show' do |toolkit|
toolkit.library_redirect '/library', :controller => 'global_toolkit_media_files', :action => 'redirect'
toolkit.library '/library/:media_type', :controller => 'global_toolkit_media_files', :action => 'index'
toolkit.press_materials '/press-materials', :controller => 'stories', :action => 'press_materials'
toolkit.brand_guidelines '/brand-guidelines', :controller => 'stories', :action => 'brand_guidelines'
toolkit.martini_contacts '/martini-contacts', :controller => 'stories', :action => 'martini_contacts'
stories(toolkit)
end
map.root :sections
end
When I go to the URL /global-toolkit/brand-guidelines1 it says unknown action but as far as I can figure out it should work.
Now,I have:
map.resources :questions, :collection => {
:query_by_student => :get
}
that matches:
query_by_student_questions GET /questions/query_by_student(.:format)
{:controller=>"questions", :action=>"query_by_student"}
I want add a "POST" request,to the same url:/questions/query_by_student,but the action should be "post_by_student"
waht shall I do?
怎么在Rails的REST基础上对自己定义的url,实现不同http方法对应不同action?
我现在有这:
map.resources :questions, :collection => {
:query_by_student => :get
}
对应路由信息:
query_by_student_questions GET /questions/query_by_student(.:format)
{:controller=>"questions", :action=>"query_by_student"}
我想加一个post请求,同样到/questions/query_by_student,但是action为post_by_student
怎么写?
I don't have a testing app but with rails 2.2, you can try
map.resources :questions, :collection => {
:query_by_student => [:get, :post]
}
and see what it looks like.
Otherwise, you can probably do it manually with something like
map.connect '/questions/query_by_student', :conditions => { :method => :get }, :controller => 'questions', :action => 'query_by_student'
map.connect '/questions/query_by_student', :conditions => { :method => :post }, :controller => 'questions', :action => 'post_by_student'
Hey! I am trying to set up routes in a Rails application so that, depending on the type of parameter passed, Rails sends the request to a different action.
I have courses which have an attribute state which is a string with a two letter state abbreviation. When a user visits /courses/1, I want Rails to display the show action in the courses controller (and pass the parameter as :id). When a user visits /courses/CO though, I want Rails to display the index action and pass the parameter as :state.
So /courses/1 would be equivalent to
:controller => 'courses', :action => 'show', :id => '1'
And /courses/CO would be equivalent to
:controller => 'courses', :action => 'index', :state => 'CO'
I have tried this:
map.resources :courses, :except => { :index, :show }
map.connect 'courses/:state', :controller => 'courses', :action => 'index', :state => /[A-Z]{2}/
map.connect 'courses/:id', :controller => 'courses', :action => 'show', :id => /[0-9]+/
But it breaks (the rails server wont even start). I don't usually do things like this with routes, so I am outside of my know-how. Thanks!
Edit: Fixed a typo, thanks JC.
Current solution looks like this:
map.resources :courses, :except => [ :index, :show ]
map.courses '/courses', :controller => 'courses', :action => 'index', :state => 'AL', :method => :get
map.courses '/courses/:state', :controller => 'courses', :action => 'index', :requirements => { :state => /[A-Z]{2}/ }, :method => :get
map.course '/courses/:id', :controller => 'courses', :action => 'show', :requirements => { :id => /[0-9]+/ }, :method => :get
This works, but you will need to go edit all your links to the index to say things like courses_path('AA') and you won't be able to use some of the nice helpers, like form_for, which assume you are following the convention that #create is simply #index with a POST request. (Get comfortable with form_tag)
ActionController::Routing::Routes.draw do |map|
map.resources :courses, :except => [ :index, :show ]
map.courses '/courses/:state', :controller => 'courses', :action => 'index', :requirements => { :state => /[A-Z]{2}/ } , :method => :get
map.course '/courses/:id', :controller => 'courses', :action => 'show', :requirements => { :id => /[0-9]+/ } , :method => :get
end
It will keep your routes named the same, though.
(by the way, your /co does not match your regex, which requires upper case chars)
Fun aside: Do we really need the abstraction of a router? http://blog.peepcode.com/tutorials/2010/rethinking-rails-3-routes
I'm afraid this won't work since the structure that maps paths to controllers and actions is setup on start of the rails application, parameter handling happens at request time.
What you could do is to match the :id-parameter in the show-action of the CoursesController against a list of valid states and then either redirect or render a different action.
Hope this helps.
I'm trying to implement custom dynamic error pages following this post:
http://www.perfectline.co.uk/blog/custom-dynamic-error-pages-in-ruby-on-rails
I did exactly what the blog post says. I included config.action_controller.consider_all_requests_local = false in my environment.rb. But is not working.
My browser shows:
Routing Error
No route matches "/555" with {:method=>:get}
So, it looks like the rescues are not fired.
I get the following in my log file:
ActionController::RoutingError (No route matches "/555" with {:method=>:get}):
Rendering rescues/layout (not_found)
Is there some routing interfering with the code? I'm not sure what to look for. I'm running rails 2.3.5.
Here is the routes.rb file:
ActionController::Routing::Routes.draw do |map|
# routing van property-url
map.connect 'buy/:property_type_plural/:province/:city/:address/:house_number', :controller => 'properties' , :action => 'show', :id => 'whatever'
map.myimmonatie 'myimmonatie' , :controller => 'myimmonatie/properties', :action => 'index'
map.login "login", :controller => "user_sessions", :action => "create", :conditions => {:method => :post}
map.login "login", :controller => "user_sessions", :action => "new"
map.logout "logout", :controller => "user_sessions", :action => "destroy"
map.buy "buy", :controller => 'buy'
map.sell "sell", :controller => 'sell'
map.home "home", :controller => 'home'
map.disclaimer "disclaimer", :controller => 'disclaimer'
map.sign_up "sign_up", :controller => 'users', :action => :new
map.contact "contact", :controller => 'contact'
map.resources :user_sessions
map.resources :contact
map.resources :password_resets
map.resources :messages
map.resources :users, :only => [:index,:new,:create,:activate,:edit,:profile,:password]
map.resources :images
map.resources :activation , :only => [:new,:resend]
map.resources :email
map.resources :properties, :except => [:index,:destroy]
map.namespace :admin do |admin|
admin.resources :users
admin.resources :properties
admin.resources :order_items, :as => :orders
admin.resources :blog_posts, :as => :blog
end
map.connect 'myimmonatie/:action' , :controller => 'users', :id => 'current', :requirements => {:action => /(profile)|(password)|(email)/}
map.namespace :myimmonatie do |myimmonatie|
myimmonatie.resources :messages, :controller => 'messages'
myimmonatie.resources :password, :as => "password", :controller => 'users', :action => 'password'
myimmonatie.resources :properties , :controller => 'properties'
myimmonatie.resources :orders , :only => [:index,:show,:create,:new]
end
map.root :controller => "home"
map.connect ':controller/:action'
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
end
ActionController::Routing::Translator.translate_from_file('config','i18n-routes.yml')
The code works, something is wrong with the line in my environment.rb
config.action_controller.consider_all_requests_local = false
It seems to be overridden somewhere.
So, CASE CLOSED, thanks!
Rails detects when you are browsing with ip 127.0.0.1 and shows you the development environment errors even if you are in production environment. You should try accessing from a different machine to get the proper errors.
Is it possible to map a subdomain to a resource? I have a company model. Currently, using subdomain_fu, my routing file contains:
map.company_root '', :controller => 'companies', :action => 'show',
:conditions => { :subdomain => /.+/ }
My Company model contains a "subdomain" column.
Whilst this works as intended, it's a named route and isn't restful. Essentially, I need to map "name.domain.com" to the show action for the companies controller. Is a named route the way to go, or can I use a resource route?
One can pass conditions to a resource route as well as a named route. In an application I am involved with everything is scoped to an account. A :before_filter loads the account using the subdomain. Thus for resources scoped to an account, we want to scope the routes to urls with subdomains. The DRY way to do this is to use map with options:
map.with_options :conditions => {:subdomain => /.+/} do |site|
site.resources :user_sessions, :only => [:new, :create, :destroy]
site.resources :users
site.login 'login', :controller => "user_sessions", :action => "new"
site.logout 'logout', :controller => "user_sessions", :action => "destroy"
…
end
map.connect 'accounts/new/:plan', :controller => "accounts", :action => "new"
map.resources :accounts, :only => [:new, :create]
As you can see a named route will accept a conditions hash with a subdomain too. You can also adopt the approach Ryan illustrated above or you can specify conditions on a per resource basis:
map.resources :users, :conditions => {:subdomain => /.+/}
I don't know of a way to do this with map.resources. It does accept a :conditions option but I'm not sure how to remove the /companies/ portion of the URL. However, map.resources is primarily a convenient way to generate a bunch of named routes, which you can do manually. Something like this.
map.company '', :controller => 'companies', :action => 'show', :conditions => { :subdomain => /.+/, :method => :get }
map.new_company 'new', :controller => 'companies', :action => 'new', :conditions => { :subdomain => /.+/, :method => :get }
map.edit_company 'edit', :controller => 'companies', :action => 'edit', :conditions => { :subdomain => /.+/, :method => :get }
map.connect '', :controller => 'companies', :action => 'create', :conditions => { :subdomain => /.+/, :method => :post }
map.connect '', :controller => 'companies', :action => 'update', :conditions => { :subdomain => /.+/, :method => :put }
map.connect '', :controller => 'companies', :action => 'destroy', :conditions => { :subdomain => /.+/, :method => :delete }
Untested, but it should get you close.
Here's a complete example implementation of Rails 3 subdomains with authentication (along with a detailed tutorial). It's much easier to do this in Rails 3 than in Rails 2 (no plugin required).
Using the resource linked from Daniel's answer, in Rails 3 the way to route '/' to a different controller depending on the subdomain is as follows:
match '/' => 'somecontroller#action', :constraints => { :subdomain => 'yoursubdomain' }