Rails route to specific action for resource - ruby-on-rails

I'm trying to get the url for given params:
url_for({
:action => "show",
:controller => "questions",
:dashboard_id => "123",
:dashboard_type => "mono",
:question_id => "1234",
:only_path => true
})
But I get this error:
ActionController::RoutingError: No route matches {:action=>"show", :controller=>"questions", :dashboard_id=>"123", :dashboard_type=>"mono", :question_id=>"1234"}
In my routes.rb file, I have this configuration:
resources :dashboards, :only => [:index, :all, :create] do
resources :questions, :path => '/:dashboard_type/questions'
end
What seems to be the problem?

Replace :question_id with :id
It should be
url_for({
:action => "show",
:controller => "questions",
:dashboard_id => "123",
:dashboard_type => "mono",
:id => "1234",
:only_path => true
})
As there is no :question_id
dashboard_question GET /dashboards/:dashboard_id/:dashboard_type/questions/:id(.:format) questions#show

Related

What does ActionController::Routing::Routes.draw do |map| do?

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.

How to implement different http method match different action with the url defined by myself based on Rails` REST

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'

Is there a better way to do with_options in Rails 3 routes?

Here are my Rails 2 routes:
map.with_options :controller => 'foo', :conditions => { :method => :post } do |foo|
foo.one 'one', :action => 'one'
foo.two 'two', :action => 'two'
foo.with_options :special_flag => 'true', :path_prefix => 'special_prefix',
:conditions => { :method => :get } do |bar|
bar.three '', :action => 'for_blank'
bar.four 'another', :action => 'for_another'
end
end
How do I convert this sort of thing to Rails 3? Just keep using with_options in the same way? It becomes wordier in some cases because instead of doing
match '' => 'foo#for_blank'
I'm doing
match '', :action => 'for_blank'
Yeah, with_options still works in Rails 3. Try this out:
map.with_options :controller => 'foo', :via => :post do
match 'one', :action => 'one' #automatically generates one_* helpers
match 'two', :action => 'two' #automatically generates two_* helpers
foo.with_options :special_flag => 'true', :path => 'special_prefix', :via => :get do
match '', :action => 'for_blank'
match 'another', :action => 'for_another', :as => "four" # as will change the helper methods names
end
end
The :via option replaces your ugly conditions hash with a much nicer syntax.
Like this:
#JSON API
defaults :format => 'json' do
get "log_out" => "sessions#destroy", :as => "log_out"
get "log_in" => "sessions#new", :as => "log_in"
get "sign_up" => "users#new", :as => "sign_up"
resources :users, :sessions
end
Try to stick to the methods the routes provide. They are very powerful in Rails 3 and should provide everything you need. See http://guides.rubyonrails.org/routing.html for more details

Custom dynamic error pages in Ruby on Rails not working

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.

Rails: Routing subdomain to a resource

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' }

Resources