I am using Ruby on Rails 3.0.9 and I would like to know why I get the error described below and how can I solve that.
In my /views/articles/categories/_content.html.erb file I have:
...
<%= link_to("New article", {:controller => content[:article_controller], :action => 'new'}) %>
...
If I set the content[:article_controller] to (both setting true and false for the :only_path option)
1. content[:article_controller] = 'articles'
2. content[:article_controller] = '/articles'
3. content[:article_controller] = '/articles/'
4. content[:article_controller] = '/'
4. content[:article_controller] = ''
I get respectively the following errors (note :controller values):
1. `ActionView::Template::Error (No route matches {:controller=>"articles/categories/articles", :action=>"new"})`
2. `ActionView::Template::Error (No route matches {:controller=>"articles//articles", :action=>"new"})`
3. `ActionView::Template::Error (No route matches {:controller=>"articles/", :action=>"new"})`
4. `ActionView::Template::Error (No route matches {:controller=>"articles//", :action=>"new"})`
4. `ActionView::Template::Error (No route matches {:controller=>"articles/categories/", :action=>"new"})`
Is it a Ruby on Rails bug or is it my fault? What is the problem and how can I solve that making the link_to properly work?
However I can solve that problem by using:
<%= link_to("New article", {:controller => '../', :action => 'new'}) %>
But why it works with '.../' but not in other ways?
I noticed that some time the controller path for which I try to set the content[:article_contr8oller] seems to relying on the "base" current controller path that is handling the view file (the controller file is app/controllers/articles/categories/concerns_controller.rb - read below for more information)... why it happens?
It also happens using url_for:
url_for(:controller => 'articles', :action => 'new')
Running the rake routes command I get the following:
articles_categories GET /articles/categories(.:format) {:action=>"index", :controller=>"articles/categories"}
POST /articles/categories(.:format) {:action=>"create", :controller=>"articles/categories"}
new_articles_category GET /articles/categories/new(.:format) {:action=>"new", :controller=>"articles/categories"}
edit_articles_category GET /articles/categories/:id/edit(.:format) {:action=>"edit", :controller=>"articles/categories"}
articles_category GET /articles/categories/:id(.:format) {:action=>"show", :controller=>"articles/categories"}
PUT /articles/categories/:id(.:format) {:action=>"update", :controller=>"articles/categories"}
DELETE /articles/categories/:id(.:format) {:action=>"destroy", :controller=>"articles/categories"}
articles GET /articles(.:format) {:action=>"index", :controller=>"articles"}
POST /articles(.:format) {:action=>"create", :controller=>"articles"}
new_article GET /articles/new(.:format) {:action=>"new", :controller=>"articles"}
edit_article GET /articles/:id/edit(.:format) {:action=>"edit", :controller=>"articles"}
article GET /articles/:id(.:format) {:action=>"show", :controller=>"articles"}
PUT /articles/:id(.:format) {:action=>"update", :controller=>"articles"}
DELETE /articles/:id(.:format) {:action=>"destroy", :controller=>"articles"}
P.S.: If you need more information, let me know and I will update the question as well.
UPDATE I
In my route file I have:
namespace :articles do articles :categories end
scope :path => 'articles/categories/:id', :controller => 'articles/categories/concerns' do
...
end
resources :articles
UPDATE II
In my view /views/articles/categories/_content.html.erb files I have:
<div class="links">
<%= link_to("New article", {:controller => content[:article_controller], :action => 'new'}) %>
</div>
In my Articles::Categories::ConcernsController (that is, in the app/controllers/articles/categories/concerns_controller.rb file) I have:
def show
#articles_category = Articles::Category.find(params[:id])
respond_to do |format|
format.html {
render :partial => '/views/articles/categories/_content.html.erb',
:locals => {
:content => {
:article_controller => '/articles'
}
}
format.js {
...
end
end
end
Did you try using symbols? I think they are more "direct".
<%= link_to("New article", {:controller => content[:article_controller].to_sym, :action => :new}) %>
Did you try using a relativ path?
<%= link_to("New article", {:controller => "../#{content[:article_controller]}", :action => 'new'}) %>
Why aren't you using link_to 'New article', new_article_path? Why use the old, tired url_for ... when you can use the named path/url helper (new_article_url).
Related
rails 3.1
rake routes for admin/sections_contoller
trigger_admin_section GET /admin/sections/:id/trigger(.:format) {:action=>"trigger", :controller=>"admin/sections"}
admin_sections GET /admin/sections(.:format) {:action=>"index", :controller=>"admin/sections"}
POST /admin/sections(.:format) {:action=>"create", :controller=>"admin/sections"}
new_admin_section GET /admin/sections/new(.:format) {:action=>"new", :controller=>"admin/sections"}
edit_admin_section GET /admin/sections/:id/edit(.:format) {:action=>"edit", :controller=>"admin/sections"}
admin_section GET /admin/sections/:id(.:format) {:action=>"show", :controller=>"admin/sections"}
PUT /admin/sections/:id(.:format) {:action=>"update", :controller=>"admin/sections"}
DELETE /admin/sections/:id(.:format) {:action=>"destroy", :controller=>"admin/sections"}
routes.rb
namespace :admin do
resources :sections do
resources :items
resources :parameters
get :trigger, :on => :member
end
...
end
view
<%= link_to "Add a section", new_admin_section_path, :class=>'add-btn' %>
generated link
http://localhost:3000/admin/sections/new
result
No route matches {:action=>"show", :controller=>"admin/sections",
:id=>#<Section id: nil, ..., meta_description: nil}
strange bug or my mistake. other controllers has similar routes and all works fine.
for ex.:
<%= link_to 'Add a group', new_admin_group_path, :class=>'add-btn' %>
works GREAT!
please, help or i'll kill myself someday
upd1 same problem on heroku with this app.
upd2 join github issue: https://github.com/rails/rails/issues/4704
i found the answer.
once i put this string in view 'admin/section/_form'
<%= link_to 'delete', admin_section_path(#section), :method => :delete, :confirm => "Sure?" %>
i used this form for creating and editing. so combination of new object and deleting link for it caused the bug.
i used debugger for analysis.
Look at your "create" method in sections_controller.
I guess your section is correctly created but it redirect to "show" action. And "show" view may not exist.
Have you checked your database ? Is the section saved ?
During cucumber tests, I get the following error:
No route matches "/companies/29/update_owner"
I am not sure what I am doing wrong, but im sure its something stupid.
I have the following routes:
company_update_owner POST /companies/:company_id/update_owner(.:format) {:controller=>"companies", :action=>"update_owner"}
company_set_owner /companies/:company_id/set_owner(.:format) {:controller=>"companies", :action=>"set_owner"}
companies GET /companies(.:format) {:action=>"index", :controller=>"companies"}
POST /companies(.:format) {:action=>"create", :controller=>"companies"}
new_company GET /companies/new(.:format) {:action=>"new", :controller=>"companies"}
edit_company GET /companies/:id/edit(.:format) {:action=>"edit", :controller=>"companies"}
company GET /companies/:id(.:format) {:action=>"show", :controller=>"companies"}
PUT /companies/:id(.:format) {:action=>"update", :controller=>"companies"}
DELETE /companies/:id(.:format) {:action=>"destroy", :controller=>"companies"}
I have tried:
company_update_owner_path(:company_id => #company.id)
and
company_update_owner_path(#company)
update:
= form_for #company, :url => company_update_owner_path(:company_id => #company.id), :method => :put do |f|
Any help would be greatly appreciated.
Here is the code in routes.rb:
resources :companies do
match '/update_owner' => 'companies#update_owner', :as => :update_owner, :via => :post
match '/set_owner' => 'companies#set_owner', :as => :set_owner
end
you need to remove the ":method=>:put"
Your route is declared as a POST but you're doing a PUT in the form. Fix either the route or the form and you'll nail it.
Would leave this as a comment, but the fromatting gets jacked.
If you're not aware, you can also define those routes slightly differently, too:
resources :companies do
member do
post "update_owner"
get "set_owner"
end
end
root :to => "index#home"
#public tattoo viewing and submissions
match "/submit" => "index#new", :via => :get
match "/tattoo" => "index#create", :via => :post
match "/tattoo/:id" => "index#show", :via => :get
match "/tagged" => "index#tagged", :via => :get
match "/tattoo/:id" => "index#destroy", :via => :delete
match "/tattoos" => "index#index", :via => :get
members section and its nested images
resources :members, :except => [:new, :create] do
resources :tattoos
end
Thats whats in my routes.rb file. They produce:
root /(.:format) {:controller=>"index", :action=>"home"}
submit GET /submit(.:format) {:controller=>"index", :action=>"new"}
tattoo POST /tattoo(.:format) {:controller=>"index", :action=>"create"}
GET /tattoo/:id(.:format) {:controller=>"index", :action=>"show"}
tagged GET /tagged(.:format) {:controller=>"index", :action=>"tagged"}
DELETE /tattoo/:id(.:format) {:controller=>"index", :action=>"destroy"}
tattoos GET /tattoos(.:format) {:controller=>"index", :action=>"index"}
members GET /members(.:format) {:action=>"index", :controller=>"members"}
edit_member GET /members/:id/edit(.:format) {:action=>"edit", :controller=>"members"}
member GET /members/:id(.:format) {:action=>"show", :controller=>"members"}
PUT /members/:id(.:format) {:action=>"update", :controller=>"members"}
DELETE /members/:id(.:format) {:action=>"destroy", :controller=>"members"}
But i have a problem. For some reason, when I try to go to mysite.com/submit
I used to get this error
No route matches {:controller=>"images"}
on
<%= form_for #tattoo, :html =>{:multipart => true} do |f| %>
but that has magically changed to:
undefined method `images_path'
on the same line.
when my controller has this:
indexcontroller
def new
#tattoo = Image.new
end
def create
#tattoo = Image.new(params[:image])
if #tattoo.save
flash[:success] = "Tattoo sent in for approval!"
redirect_to(images_path)
else
render :action => "new"
end
end
And then this link_to:
<%= link_to "Manage tattoos", member_tattoos_path() %>
give me this error:
No route matches {:controller=>"tattoos"}
I thought I was beginning to understand routes and had a decent grasp but I dont get whats going on!
You need to pass in a member object to edit_member_path.
<%= link_to "Edit profile", edit_member_path(#member) %>
edit_member_path should know the id of the member you want to edit. Please try
<%= link_to "Edit profile", edit_member_path(#member) %>
For No route matches {:controller=>"images"}; since the action image is not defined in your route, please try to stop and restart the server and check if there is any plugin like Paperclip in place.
I'm trying to make a two-step confirmation like heroku using Devise.
My routes:
devise_for :user, :controllers => {:confirmations => "confirmations", :registrations => "registrations" }
put "confirm_account", :to => "confirmations#confirm_account"
Here's my alternate confirmation controller:
class ConfirmationsController < Devise::ConfirmationsController
def show
#account = User.find_by_confirmation_token(params[:confirmation_token])
if !#account.present?
render_with_scope :new
end
end
def confirm_account
#account = User.find(params[:account][:confirmation_token])
if #account.update_attributes(params[:account]) and #account.password_match?
#account = User.confirm_by_token(#account.confirmation_token)
set_flash_message :notice, :confirmed
sign_in_and_redirect("user", #account)
else
render :action => "show"
end
end
end
Here's my show.html.erb:
<%= form_for(resource, :as => resource_name, :url => confirm_account_path(resource_name)) do |f| %>
<%= f.label :email %>
<%= #account.email %>
<%= f.hidden_field :confirmation_token %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
<%= f.submit 'Confirm Account' %>
<%= link_to 'Home', root_url %>
<%= render :partial => 'devise/shared/links' %>
<% end %>
When I click confirm after filling out the password (after clicking confirm in the confirmation email). I'm routed to /confirm_account.user That's pretty weird, right? What's going on to cause this problem?
Edit
rake routes returns:
new_user_session GET /user/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
user_session POST /user/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_user_session GET /user/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /user/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /user/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /user/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /user/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
cancel_user_registration GET /user/cancel(.:format) {:action=>"cancel", :controller=>"registrations"}
user_registration POST /user(.:format) {:action=>"create", :controller=>"registrations"}
new_user_registration GET /user/sign_up(.:format) {:action=>"new", :controller=>"registrations"}
edit_user_registration GET /user/edit(.:format) {:action=>"edit", :controller=>"registrations"}
PUT /user(.:format) {:action=>"update", :controller=>"registrations"}
DELETE /user(.:format) {:action=>"destroy", :controller=>"registrations"}
user_confirmation POST /user/confirmation(.:format) {:action=>"create", :controller=>"confirmations"}
new_user_confirmation GET /user/confirmation/new(.:format) {:action=>"new", :controller=>"confirmations"}
GET /user/confirmation(.:format) {:action=>"show", :controller=>"confirmations"}
user_unlock POST /user/unlock(.:format) {:action=>"create", :controller=>"devise/unlocks"}
new_user_unlock GET /user/unlock/new(.:format) {:action=>"new", :controller=>"devise/unlocks"}
GET /user/unlock(.:format) {:action=>"show", :controller=>"devise/unlocks"}
confirm_account PUT /confirm_account(.:format) {:action=>"confirm_account", :controller=>"confirmations"}
editreject_admin GET /admin/:id/editreject(.:format) {:action=>"editreject", :controller=>"admin"}
reject_admin GET /admin/:id/reject(.:format) {:action=>"reject", :controller=>"admin"}
accept_admin GET /admin/:id/accept(.:format) {:action=>"accept", :controller=>"admin"}
entries_admin_index GET /admin/entries(.:format) {:action=>"entries", :controller=>"admin"}
preferences_admin_index GET /admin/preferences(.:format) {:action=>"preferences", :controller=>"admin"}
admin_index GET /admin(.:format) {:action=>"index", :controller=>"admin"}
about_entries GET /entries/about(.:format) {:action=>"about", :controller=>"entries"}
all_entries GET /entries/all(.:format) {:action=>"all", :controller=>"entries"}
myentries_entries GET /entries/myentries(.:format) {:action=>"myentries", :controller=>"entries"}
rate_entry GET /entries/:id/rate(.:format) {:action=>"rate", :controller=>"entries"}
submit_entry PUT /entries/:id/submit(.:format) {:action=>"submit", :controller=>"entries"}
entry_comments POST /entries/:entry_id/comments(.:format) {:action=>"create", :controller=>"comments"}
entry_comment DELETE /entries/:entry_id/comments/:id(.:format) {:action=>"destroy", :controller=>"comments"}
entries GET /entries(.:format) {:action=>"index", :controller=>"entries"}
POST /entries(.:format) {:action=>"create", :controller=>"entries"}
new_entry GET /entries/new(.:format) {:action=>"new", :controller=>"entries"}
edit_entry GET /entries/:id/edit(.:format) {:action=>"edit", :controller=>"entries"}
entry GET /entries/:id(.:format) {:action=>"show", :controller=>"entries"}
PUT /entries/:id(.:format) {:action=>"update", :controller=>"entries"}
DELETE /entries/:id(.:format) {:action=>"destroy", :controller=>"entries"}
/auth/:service/callback(.:format) {:controller=>"services", :action=>"create"}
services GET /services(.:format) {:action=>"index", :controller=>"services"}
POST /services(.:format) {:action=>"create", :controller=>"services"}
root /(.:format) {:controller=>"entries", :action=>"index"}
offline /offline(.:format) {:controller=>"application", :action=>"offline"}
Edit 3
In changing
devise_for :user, :controllers => {:confirmations => "confirmations", :registrations => "registrations" } do
match "/confirm_account", :to => "confirmations#confirm_account"
end
I'm receiving :
You have a nil object when you didn't
expect it! You might have expected an
instance of Array. The error occurred
while evaluating nil.[]
{"utf8"=>"✓",
"authenticity_token"=>"dsG/e8Tw2Oi6zEDb07R/L0yDOKFEFlse+IgLbfz3Lo0=",
"user"=>{"confirmation_token"=>"",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"},
"commit"=>"Confirm Account"}
There's definitely a token in the url, though...This is actually going somewhere, though!
It looks to me like confirm_account_path doesn't exist?
If you didn't set up your routes manually, you can go ahead and set that in the config/routes.rb file, to confirmations#confirm_account.
Or, if you set Devise to use your ConfirmationsController, using new_user_confirmation_path may work too (and may not). Type rake routes in the console to see available routes. They should lead to the ConfirmationsController and the confirm_account action.
EDIT: Try editing your routes file as follows.
devise_for :user, :controllers => {:confirmations => "confirmations", :registrations => "registrations" } do
match "/confirm_account" => "confirmations#confirm_account"
end
I think the slash is important before confirm_account because it is now inside the devise_for block (which is identical to devise_scope). Otherwise it may go to users/confirm_account.
EDIT2: Use params[:user][:confirmation_token], not params[:account][:confirmation_token] in the controller. But currently it looks like the confirmation token is blank.
I'm having trouble routing a form to a custom action in Rails 3. Here are my routes:
resources :photos do
resources :comments
collection do
get 'update_states'
end
member do
put 'upload'
end
end
Here's the form_for:
form_for #photo, :remote => true, :url => { :action => upload_photo_path(#photo) }, :html => { :multipart => :true, :method => 'put' } do |f|
And here's the error message:
No route matches {:action=>"/photos/42/upload", :controller=>"photos"}
... this is especially frustrating because "photos/:id/upload" is exactly the correct action for this form.
What am I missing?
EDITS - Here are the original Photo-related routes:
photo_comments GET /photos/:photo_id/comments(.:format) {:action=>"index", :controller=>"comments"}
POST /photos/:photo_id/comments(.:format) {:action=>"create", :controller=>"comments"}
new_photo_comment GET /photos/:photo_id/comments/new(.:format) {:action=>"new", :controller=>"comments"}
edit_photo_comment GET /photos/:photo_id/comments/:id/edit(.:format) {:action=>"edit", :controller=>"comments"}
photo_comment GET /photos/:photo_id/comments/:id(.:format) {:action=>"show", :controller=>"comments"}
PUT /photos/:photo_id/comments/:id(.:format) {:action=>"update", :controller=>"comments"}
DELETE /photos/:photo_id/comments/:id(.:format) {:action=>"destroy", :controller=>"comments"}
update_states_photos GET /photos/update_states(.:format) {:action=>"update_states", :controller=>"photos"}
upload_photo PUT /photos/:id/upload(.:format) {:action=>"upload", :controller=>"photos"}
photos GET /photos(.:format) {:action=>"index", :controller=>"photos"}
POST /photos(.:format) {:action=>"create", :controller=>"photos"}
new_photo GET /photos/new(.:format) {:action=>"new", :controller=>"photos"}
edit_photo GET /photos/:id/edit(.:format) {:action=>"edit", :controller=>"photos"}
photo GET /photos/:id(.:format) {:action=>"show", :controller=>"photos"}
PUT /photos/:id(.:format) {:action=>"update", :controller=>"photos"}
DELETE /photos/:id(.:format) {:action=>"destroy", :controller=>"photos"}
Here are the relevant routes when I changed the route to match 'upload':
photo_comments GET /photos/:photo_id/comments(.:format) {:action=>"index", :controller=>"comments"}
POST /photos/:photo_id/comments(.:format) {:action=>"create", :controller=>"comments"}
}
new_photo_comment GET /photos/:photo_id/comments/new(.:format) {:action=>"new", :controller=>"comments"}
edit_photo_comment GET /photos/:photo_id/comments/:id/edit(.:format) {:action=>"edit", :controller=>"comments"}
photo_comment GET /photos/:photo_id/comments/:id(.:format) {:action=>"show", :controller=>"comments"}
PUT /photos/:photo_id/comments/:id(.:format) {:action=>"update", :controller=>"comments"}
DELETE /photos/:photo_id/comments/:id(.:format) {:action=>"destroy", :controller=>"comments"}
update_states_photos GET /photos/update_states(.:format) {:action=>"update_states", :controller=>"photos"}
upload_photo /photos/:id/upload(.:format) {:action=>"upload", :controller=>"photos"}
photos GET /photos(.:format) {:action=>"index", :controller=>"photos"}
POST /photos(.:format) {:action=>"create", :controller=>"photos"}
new_photo GET /photos/new(.:format) {:action=>"new", :controller=>"photos"}
edit_photo GET /photos/:id/edit(.:format) {:action=>"edit", :controller=>"photos"}
photo GET /photos/:id(.:format) {:action=>"show", :controller=>"photos"}
PUT /photos/:id(.:format) {:action=>"update", :controller=>"photos"}
DELETE /photos/:id(.:format) {:action=>"destroy", :controller=>"photos"}
Unfortunately 'match' didn't work any better...
-- EDIT --
Just to confirm another scenario here... with this in the routes:
resources :photos do
resources :comments
collection do
get 'update_states'
end
member do
match 'upload'
end
end
and this in the view:
form_for #photo, :remote => true, :url => { :action => 'upload' }, :html => { :multipart => :true, :id => 'photo_upload' } do |f|
I still get:
No route matches {:action=>"upload", :controller=>"photos"}
What if you did just :url => upload_photo_path(#photo)?
It seems a little strange that you'd be uploading to a member though. Is this just a creation method (in which case you should just POST to the collection path)?
I had the same problem and finally worked through to a solution which I'm not sure was reached in the above case, since the original poster moved on to another approach.
My routes had
resources :members do
member do
get "invite"
post 'register'
end
end
And "rake routes" included
register_member POST /members/:id/register(.:format) {:protocol=>"http", :action=>"register", :controller=>"members"}
Yet I kept getting the error
Started POST "/members/149/register" for 127.0.0.1 at 2012-04-13 13:18:35 -0700
ActionController::RoutingError (No route matches "/members/149/register"):
Rendered /Users/lisa/.rvm/gems/ruby-1.9.2-p180#stv/gems/actionpack-3.0.9/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (1.1ms)
and the problem was limited only to the form generated by Rails according to the below form_for (note I confirmed this using HTTP client to manually POST to the URL and saw it was finding the route)
<%= form_for #account, :url => register_member_path(#account.id) do |account_form| %>
...
I checked the method, I checked the path, everything looked good. What I finally noticed, scouring the generated form line by line:
<form accept-charset="UTF-8" action="/members/149/register" class="edit_member" id="edit_member_149" method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓" />
<input name="_method" type="hidden" value="put" />
<input name="authenticity_token" type="hidden" value="74pkMgRHfdowSfzjJGMILkAsivVNrJZ0iWYXRUgxyF0=" />
</div>
...
Notice the hidden input name="_method". I wish the fact that Rails was interpreting this as a PUT had shown up in the logs, that would have made my debugging a lot faster. I fixed it by telling the form explicitly to use the POST method, which of course it was already, but telling it that removed the hidden _method override. I assume there's some facet about #account which triggered Rails to use the _method parameter, but #account should be an existing record.
Your url parameter should be
:url => { :action => "upload" }
(Original reply)
I would bet it's because your route expects a PUT and your form is sending a POST (probably because #photo = Photo.new). You have several options:
Change your route to post 'upload'
Create your form with form_for #photo, :as => :post with the rest of your arguments
Make sure #photo is an existing record (e.g. by calling create instead of new)
The most appropriate choice is probably one of the first 2.