Reputation: 11533
I am new to Rails3, and I'm building very simple app (in which I don't want AJAX). Anyway, I have the index
and create
actions. The index
action contains form:
<%= form_for @message, url: promote_index_path do |f| %>
...
<% end %>
My promote_controller
looks like this:
def index
@message = Message.new url: @last_video, message_body: @last_message
end
def create
@message = current_user.messages.new(params[:message])
@message.get_video_id
if @message.save
redirect_to promote_index_url, flash: {notice: "Promotion has been started"}
else
render 'index'
end
end
This all works fine, except for when form is submitted successfully, and notice is flashed, if user hits F5
, the form resubmits itself. Which should not be the case, since I am doing redirect_to
after successful save. I believe I am doing something fundamentally wrong here, so please help me out.
EDIT:
Here is my routes.rb
resources :home
resources :find
resources :promote
resources :settings
root to: 'home#index'
match 'auth/:provider/callback', to: 'sessions#create'
match 'auth/failure', to: redirect('/')
match 'logout', to: 'sessions#destroy', as: 'logout'
match 'find', to: 'find#index', as: 'find'
match 'promote', to: 'promote#index', as: 'promote'
match 'settings', to: 'settings#index', as: 'settings'
And here is my rake routes
Jans-MacBook-Pro-2:tp3 jan$ rake routes
settings_index GET /settings/index(.:format) settings#index
home_index GET /home(.:format) home#index
POST /home(.:format) home#create
new_home GET /home/new(.:format) home#new
edit_home GET /home/:id/edit(.:format) home#edit
home GET /home/:id(.:format) home#show
PUT /home/:id(.:format) home#update
DELETE /home/:id(.:format) home#destroy
find_index GET /find(.:format) find#index
POST /find(.:format) find#create
new_find GET /find/new(.:format) find#new
edit_find GET /find/:id/edit(.:format) find#edit
find GET /find/:id(.:format) find#show
PUT /find/:id(.:format) find#update
DELETE /find/:id(.:format) find#destroy
promote_index GET /promote(.:format) promote#index
POST /promote(.:format) promote#create
new_promote GET /promote/new(.:format) promote#new
edit_promote GET /promote/:id/edit(.:format) promote#edit
promote GET /promote/:id(.:format) promote#show
PUT /promote/:id(.:format) promote#update
DELETE /promote/:id(.:format) promote#destroy
settings GET /settings(.:format) settings#index
POST /settings(.:format) settings#create
new_setting GET /settings/new(.:format) settings#new
edit_setting GET /settings/:id/edit(.:format) settings#edit
setting GET /settings/:id(.:format) settings#show
PUT /settings/:id(.:format) settings#update
DELETE /settings/:id(.:format) settings#destroy
root / home#index
/auth/:provider/callback(.:format) sessions#create
auth_failure /auth/failure(.:format) :controller#:action
logout /logout(.:format) sessions#destroy
find /find(.:format) find#index
promote /promote(.:format) promote#index
settings /settings(.:format) settings#index
EDIT: The issue seems to be in Google Chrome.
Upvotes: 2
Views: 2212
Reputation: 8209
I had the same problem and eventually tracked it down to a bug in Chrome (https://code.google.com/p/chromium/issues/detail?id=177855)
The work around I used is just to add some get parameters. Here's how I dealt with both the bug and the frustration. The result may not be appropriate for all scenarios. Fortunately my app is internal.
def create
@message = current_user.messages.new(params[:message])
@message.get_video_id
if @message.save
flash[:notice] = "Promotion has been started"
redirect_to promote_index_url(chrome_bug_workaround: 177855)
else
render 'index'
end
end
Another alternative is to create a collection route that is basically an alias for index.
In routes.rb
:
match 'promote/all' => 'promote#index', :as => 'all_promotions'
In promote_controller.rb
:
def create
@message = current_user.messages.new(params[:message])
@message.get_video_id
if @message.save
redirect_to all_promotions_url, flash: {notice: "Promotion has been started"}
else
render 'index'
end
end
As an aside, your find
, promote
, and settings
match routes appear to be redundant with the resource routes' index actions.
Upvotes: 2
Reputation: 19304
Try changing your methods to this:
def index
@message = Message.new url: @last_video, message_body: @last_message
respond_to do |format|
format.html
end
end
def create
@message = current_user.messages.new(params[:message])
@message.get_video_id
respond_to do |format|
if @message.save
format.html {redirect_to promote_index_url, notice: "Promotion has been started"}
else
render 'index'
end
end
end
Upvotes: 0