Rails Routing Error - ruby-on-rails

In routes.rb I have:
get "survey/show" => "survey#show"
post "survey/step_2" => "survey#step_2"
post "survey/step_3" => "survey#step_3"
And in step_2.html.erb I have:
<%= form_for #result, :url => { :controller => 'survey', :action => 'step_3' } do |f| %>
And in survey_controller.rb I have:
def step_2
#result = Result.new(params[:result])
if #result.save
session[:result_id] = #result.id
render :action => "step_2"
else
render :action => "show"
end
end
def step_3
#result = Result.find(session[:result_id])
if #result.update_attributes(params[:result])
render :action => "step_3"
else
render :action => "step_2"
end
end
And when I submit the form on step_2 I get the following error:
No route matches "/survey/step_3"

I believe Rails form_for method may be making that a PUT request, since the #result object has an id. I believe you should change your form_for line to:
<%= form_for #result,
:url => { :controller => 'survey', :action => 'step_3' },
:html => { :method => :post} do |f| %>
or change the route type to put in routes.rb

You have to use match.
match 'survey/step_3' => 'survey#step_3', :via => 'post'
I might be wrong about the :via, but it's something like that.

Related

Custom Post action not passing param

I have a a custom post request as follows:
= form_for(#property, :html => {:id => "promo-upload-form"} , :url => url_for(:action => 'update_promo_image'),:method => :post) do |f|
The route is as follows:
post 'properties/update_promo_image', :as => 'update_promo_image'
It takes me to this action on controller:
def update_promo_image
#property = Property.find(params[:id])
if #property.update(property_params)
respond_to do |format|
format.html
format.js
end
else
render 'edit'
end
end
But I get the error:
Couldn't find Property without an ID
If I revert this back to the standard/default Update action it works perfectly.
Does anyone have any insight as to what I'm doing wrong please?
Thanks
Steve
Define your routes using resources and this should be easier:
routes.rb
resources :properties do
member do
post :update_promo_image
end
end
This will make an update_promo_image_property_url(object) route available.
View:
form_for(#property, :html => {:id => "promo-upload-form"} , :url => update_promo_image_property_url(#property)) do |form|
form.input :field1
form.submit
end
Which will route to your controller method (including params[:id] to identify the property) passing params[:property][:field1] for your logic. Your controller should be fine.

routing error showing that No route matches [POST] "/admin/locations/1"

I am new to ROR when i edit my location it will gives me following error
No route matches [POST] "/admin/locations/1"
here i am using rails 3.2.12
this is my location controller
class Admin::LocationsController < ApplicationController
def index
#location= Location.order("location desc")
end
def new
#location=Location.new
end
def create
#location = Location.new(params[:location])
if #location.save
# flash[:notice] = 'Location is successfully added in to list.'
redirect_to :action => 'index'
else
render :action => 'new'
end
end
def edit
#location = Location.find(params[:id])
end
def update
#location = Location.find(params[:id])
if #location.update_attributes(params[:location])
#flash[:notice] = 'Category is successfully updated.'
redirect_to :action => 'index'
else
render :action => 'index'
end
end
end
this is my edit.html.erb
<h2>Edit Location</h2>
<%= simple_form_for(:location, :url => {:action => 'update', :id => #location.id}) do |f| %>
<%= render(:partial => 'form', :locals => {:f => f}) %>
<%= submit_tag("Update",) %> <%= link_to("cancle", {:action => 'index'} )%>
<%end%>
and this is my route.rb
GuestHouse::Application.routes.draw do
devise_for :customers
namespace :admin do
resources :locations
end
and in my index.html.erb as
<%= link_to("Edit", {:action => 'edit', :id => location.id}, :class => 'btn btn-info')%>
<%= simple_form_for(:location,
:url => {:action => 'update', :id => #location.id},
:method => 'put' ) do |f| %>
Pass method in simple_form_for
For an edit form, you likely want to be using the PUT method instead of POST. It looks like you are using [SimpleForm][1], though, which normally would handle constructing the path for a given model for you. Is there any reason you are not passing your Location instance in your call to simple_form_for? I would expect something like the following:
<%= simple_form_for #location do |f| %>
...
Here your routes for admin/location like the following.
admin_locations GET /admin/locations(.:format) admin/locations#index
POST /admin/locations(.:format) admin/locations#create
new_admin_location GET /admin/locations/new(.:format) admin/locations#new
edit_admin_location GET /admin/locations/:id/edit(.:format) admin/locations#edit
admin_location GET /admin/locations/:id(.:format) admin/locations#show
PUT /admin/locations/:id(.:format) admin/locations#update
DELETE /admin/locations/:id(.:format) admin/locations#destroy
so if you want to send the form to 'update' action, you should mention the path like below.
<%= simple_form_for #location, :url => admin_location_path(#location),:html => { :method => "post"} do |f| %>

no route matches

I have a file reports/print.html.erb
in reports_controller
def print
#report = Report.find(params[:id])
respond_to do |format|
format.html { render :layout => false }
format.xml { render :xml => #report }
end
end
in routes.rb
match 'reports/print(:id)'
trying to call with
<%= link_to 'Print', report_print_path(:id => #report.id), :method => :put %>
and getting this error:
ActionController::RoutingError in Reports#show
No route matches {:action=>"print", :id=>23, :controller=>"report"}
Where am I going wrong?
Change your route to:
match 'reports/print/:id' => 'controller#print', :via => :put
That may fix it (didn't test the code though, and change the 'controller#print' part to your actual controller name.
made it work with
<%= link_to 'Print', print_url(:id => #report.id) %>
and
match 'print/(:id)' => 'reports#print', :via => :get, :as => :print
No idea why it was giving me problems, there's 4 hours of my life i'll never get back.

Rails 3 form_for nested routes for custom action

My setup: Rails 3.0.9, Ruby 1.9.2
I added a custom action to a nested resource task.
routes.rb
resources :tasks
resources :projects do
resources :tasks, :constraints => { :protocol => "http" } do
put :cancel, :on => :member
end
end
rake routes shows
cancel_project_task PUT /projects/:task_id/tasks/:id/cancel(.:format) {:protocol=>"http", :action=>"cancel", :controller=>"tasks"}
In my controller,
tasks_controller.rb
def cancel
#task = Task.find(params[:id])
respond_to do |format|
if #task.cancel
format.html { redirect_to(#task, :notice => 'Task was successfully canceled.') }
else
format.html { render :action => "edit" }
end
end
end
I need to define a form to perform the action, here's what I have currently
_form.html.erb for subscription
<%= form_for [#project, #task], :url => { :action => 'cancel' } do |f| %>
<%= f.submit "Cancel your task"%>
<% end %>
It throws an error
No route matches {:action=>"cancel", :controller=>"tasks"}
I also tried adding :method => "put" with the same error
_form.html.erb for subscription
<%= form_for [#project, #task], :url => { :action => 'cancel', :method => "put" } do |f| %>
<%= f.submit "Cancel your task"%>
<% end %>
Anyone knows the correct form_format syntax to accomplish this?
In case anyone wants the answer, here's what I had to do
<%= form_for [#project, #task], :url => cancel_project_task_path(#project, #task) do |f| %>
It took me way too long to figure this out, hopefully this helps the next unsuspecting developer.

Rails: Passing multiple parameters to form_for url?

This works great:
- form_for #user, :url => { :action => :create, :type => #type } do |f| ...
Returns /users/(id)?type=type
But in another view I need to pass TWO parameters into the URL string, and this does not work:
- form_for #user, :url => { :action => :update, :type => #type, :this => #currently_editing } do |f| ...
Returns /users/(id)?this=currently_editing
I've also tried:
- form_for #user, :url => { :action => :update, :params = params.merge({:this => #currently_editing, :type = #type})} do |f| ...
... with no luck (error: only GET requests allowed).
What I want is for it to return this: /users/(id)?this=currently_editing&type=type
Thoughts?
Why do you need to pass them into the URL string? Why not just add them as hidden fields in the form? In almost all cases you should pass the variables that way with POSTs.
I would use hidden fields, but this should work:
<% form_for #user, :url => user_path(#user.id, :type => #type, :this => #currently_editing), :method => :put do |f| -%>
:method => :put triggers the update action when using RESTful routes.
please try to this
you can pass more than one parameter in this way.
- form_for #user, :url => xxx_yyy_path(:param1 => value1, :params2 => value2, ......) do |f| ...
I think you have to move the desired querystring attributes outside of the :url option like this:
form_for #user, :url => { :action => :update }, :type => #type, :this => #currently_editing do |f|

Resources