adding tenant user inside a property view - ruby-on-rails

I'm trying to add a Tenant user inside a Property#show view. I have a form there like the following:
<%= form_for(#property.tenants) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="select">
<%= f.select :type, [['Landlord'],['Tenant']] %>
</div>
<%= f.submit "Add", %>
<% end %>
The Tenant model is as follows:
class Tenant < User
belongs_to :property
def type
"Tenant"
end
end
and the Property model is as follows:
class Property < ActiveRecord::Base
attr_accessible :address, :bathrooms, :bedrooms, :postcode, :price
belongs_to :branch
belongs_to :user
has_many :ownerships
has_many :landlords, :through => :ownerships
has_many :tenants
end
When I click on the Add button i'm magically redirected to the root path (/).
I'm expecting it to add a new tenant for that specific property that I'm viewing in the show view but it just redirects me to the root path.
Feel free to ask for any clarifications
results of rake routes:
tenants_index GET /tenants/index(.:format) tenants#index
tenants_show GET /tenants/show(.:format) tenants#show
tenants_new GET /tenants/new(.:format) tenants#new
landlords_new GET /landlords/new(.:format) landlords#new
tenants_edit GET /tenants/edit(.:format) tenants#edit
tenants_create GET /tenants/create(.:format) tenants#create
tenants_update GET /tenants/update(.:format) tenants#update
tenants_destroy GET /tenants/destroy(.:format) tenants#destroy
properties GET /properties(.:format) properties#index
POST /properties(.:format) properties#create
new_property GET /properties/new(.:format) properties#new
edit_property GET /properties/:id/edit(.:format) properties#edit
property GET /properties/:id(.:format) properties#show
PUT /properties/:id(.:format) properties#update
DELETE /properties/:id(.:format) properties#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
companies GET /companies(.:format) companies#index
POST /companies(.:format) companies#create
new_company GET /companies/new(.:format) companies#new
edit_company GET /companies/:id/edit(.:format) companies#edit
company GET /companies/:id(.:format) companies#show
PUT /companies/:id(.:format) companies#update
DELETE /companies/:id(.:format) companies#destroy
branches GET /branches(.:format) branches#index
POST /branches(.:format) branches#create
new_branch GET /branches/new(.:format) branches#new
edit_branch GET /branches/:id/edit(.:format) branches#edit
branch GET /branches/:id(.:format) branches#show
PUT /branches/:id(.:format) branches#update
DELETE /branches/:id(.:format) branches#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
agents GET /agents(.:format) users#index
POST /agents(.:format) users#create
new_agent GET /agents/new(.:format) users#new
edit_agent GET /agents/:id/edit(.:format) users#edit
agent GET /agents/:id(.:format) users#show
PUT /agents/:id(.:format) users#update
DELETE /agents/:id(.:format) users#destroy
landlords GET /landlords(.:format) users#index
POST /landlords(.:format) users#create
new_landlord GET /landlords/new(.:format) users#new
edit_landlord GET /landlords/:id/edit(.:format) users#edit
landlord GET /landlords/:id(.:format) users#show
PUT /landlords/:id(.:format) users#update
DELETE /landlords/:id(.:format) users#destroy
tenants GET /tenants(.:format) users#index
POST /tenants(.:format) users#create
new_tenant GET /tenants/new(.:format) users#new
edit_tenant GET /tenants/:id/edit(.:format) users#edit
tenant GET /tenants/:id(.:format) users#show
PUT /tenants/:id(.:format) users#update
DELETE /tenants/:id(.:format) users#destroy
root / static_pages#home
signup /signup(.:format) users#new
signin /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
dashboard /dashboard(.:format) static_pages#dashboard
help /help(.:format) static_pages#help
about /about(.:format) static_pages#about
contact /contact(.:format) static_pages#contact
properties_controller.rb
class PropertiesController < ApplicationController
# GET /properties
# GET /properties.json
def index
#properties = Property.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #properties }
end
end
def show
#property = Property.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #property }
end
end
# GET /properties/new
# GET /properties/new.json
def new
# #property = Property.new
#property = current_user.properties.build if signed_in?
respond_to do |format|
format.html # new.html.erb
format.json { render json: #property }
end
logger.debug("hello from new")
end
# GET /properties/1/edit
def edit
#property = Property.find(params[:id])
end
# POST /properties
# POST /properties.json
def create
##property = Property.new(params[:property])
#property = current_user.branch.properties.build(params[:property]) if signed_in?
respond_to do |format|
#property.user_id = current_user.id
if #property.save
format.html { redirect_to #property, notice: 'Property was successfully created.' }
format.json { render json: #property, status: :created, location: #property }
else
format.html { render action: "new" }
format.json { render json: #property.errors, status: :unprocessable_entity }
end
end
end
end

I think there are several things that doesn't seem quite right.
Try this.
Add #tenant instance variable to the show method of Properties controller.
def show
...
#tenant = #property.tenants.build
end
And modify form_for line to this.
<%= form_for #tenant do |f| %>

In your properties_controller.rb,
def show
#tenant = Tenant.new
end
Your from should then be:
<%= form_for #tenant do |f| %>
You should also add a hidden field with the ID of the property for when you submit your form.
Then for your create action in properties_controller.rb
def create
tenant = Tenant.new(params[:tenant])
tenant.property_id = params[:property_id] #This is from that hidden field with your property_id and this also assumes you have a column in your tenant table for property_id
tenant.save
#the shorter way would just be tenant = Tenate.create(params[tenant]) but I want to emphasize the property_id since this attribute is paramount to your property-tenant relationship
end
This should effectively create a form for a new tenant and when you create the actual tenant record, you will save the property ID with the new tenant record.
On another note, I would suggest moving this to the Tenants controller per Rails convention and having the form under the new action since you are really creating a new tenant record.

Related

Ruby on Rails: Adding Additional RESTFUL Actions

In my rails app I would like to have two patch methods for updating the users profile.
First, I will have an 'account_settings' GET request, which will use the standard edit/update REST action to update certain parameters. Then, I would like to have an additional 'edit_profile' and 'update_profile' actions to get a page that will allow the user to update different user attributes. Here's how it looks in my users_controller.rb for a better idea:
#For account settings page
#This is for the account settings page
#(only changing email and password)
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(account_settings_params)
flash.now[:success] = "Your settings have been successfully updated."
format.html {redirect_to #user}
else
format.html {redirect_to edit_user_path}
flash[:error] = "Please be sure to fill out your email, password, and password confirmation."
end
end
end
def edit_profile
#user = User.find(params[:id])
end
#For update profile
def update_profile
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(user_profile_params)
flash.now[:success] = "Your profile has been updated."
format.html {redirect_to #user}
else
format.html {redirect_to edit_profile_user_path}
flash[:error] = "Please be sure to fill out all the required profile form fields."
end
end
end
private
def account_settings_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
def user_profile_params
params.require(:user).permit(:name, :about_me, :location, :image_url)
end
Selection from my current routes.rb :
#Account Settings Just for Email and Password
get 'account_settings' => 'users#edit'
patch 'settings' => 'users#update'
resources :users do
member do
get :edit_profile
put :update_profile
end
end
Results of rake routes:
edit_profile_user GET /users/:id/edit_profile(.:format) users#edit_profile
update_profile_user PATCH /users/:id/update_profile(.:format) users#update_profile
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
My navbar partial:
-if logged_in?
-# Logged in links
%li
=link_to 'Logout', logout_path, method: :delete
%li
=link_to 'Account Settings',edit_user_path(#current_user)
%li
=link_to 'Edit My Profile', edit_profile_user_path(#current_user)
%li
=link_to 'View My Profile', user_path(#current_user)
%li
=link_to 'Members', users_path
On the edit_profile page, my form looks like this:
=form_for #user, path: update_profile_user_path(#user) do |f|
With my current implementation, visiting the edit_profile page and posting the form will lead back to the regular edit page with my rails server saying that the parameters were unpermitted. However, as you can see in my update_profile method in my controller, the controller method for update_profile accepts user_profile_params rather than the account_settings_params . Any insight onto why it might be doing this?
A few notes:
You don't need render "edit_profile" because that is done by default
You don't need to overwrite the edit route
I'd strongly suggest actually having a separate Profile controller, instead of trying to hack it in as extra actions on user.
That being said, the routes look like
resources :users do
member do
get :edit_profile
patch :update_profile
end
end
then your link would be to users/1/edit_profile (link_to "edit", edit_profile_path(#user)) and the form would be to <%= form_for #user, path: update_user_path(#user) %>
To add RESTful routes to the current resources you can use collection or members based on the requirement.
collection is used as a non membered resources like index action which gives a collection of objects where as show action needs an object to show. Hence member is used to get the action of a single object.
Here you can use
resources users do
resources member do
get :edit_profile
put :update_profile
end
end
You can also use
resources :users do
get :edit_profile, on: :member
put :update_profile, on: :member
end

Error concerning url parameter while testing view

Running the provided spec fails, and I think it might be related to the url parameters, being territories/:id/.
Error received :
1) territories/edit.html.erb shows a form with the data already in it
Failure/Error: <%= form_for(territory, remote: true) do |territory_form| %>
ActionView::Template::Error:
No route matches {:action=>"show", :controller=>"territories", :format=>nil, :id=>nil, :locale=>#<Territory id: 2, name: "Territory 4", lent_on: "2015-12-21", returned_on: "2015-12-21", lent_to: 6, created_at: "2015-12-23 10:04:15", updated_at: "2015-12-23 10:04:15">} missing required keys: [:id]
I'm working with form_for. I find it a bit weird that I receive an error about the url parameter in my view, while I'm not having anything directly related to it in the view code.
I've put the controller code as wel, just for clarity.
Can someone guide me how to either fix this or how to properly test this
edit.html.erb
<h1>Territories#edit</h1>
<p>Find me in app/views/territories/edit.html.erb</p>
<%= render partial: "territory_form", locals: { territory: #territory } %>
edit.html.erb_spec.rb
require 'rails_helper'
RSpec.describe "territories/edit.html.erb", type: :view, territories:true do
before(:each) do
#territory = create(:territory)
render
end
it "shows a form with the data already in it" do
puts "Body: #{rendered}"
expect(rendered).to have_css("label", :text => "Name")
expect(rendered).to have_css "input[value*='#{#territory.name}']"
end
end
routes.rb
Prefix Verb URI Pattern Controller#Action
sessions_new GET (/:locale)/sessions/new(.:format) sessions#new {:locale=>/en|nl/}
sign_up_new GET (/:locale)/sign_up/new(.:format) sign_up#new {:locale=>/en|nl/}
users GET (/:locale)/users(.:format) users#index {:locale=>/en|nl/}
edit_user GET (/:locale)/users/:id/edit(.:format) users#edit {:locale=>/en|nl/}
user GET (/:locale)/users/:id(.:format) users#show {:locale=>/en|nl/}
PATCH (/:locale)/users/:id(.:format) users#update {:locale=>/en|nl/}
PUT (/:locale)/users/:id(.:format) users#update {:locale=>/en|nl/}
DELETE (/:locale)/users/:id(.:format) users#destroy {:locale=>/en|nl/}
register GET (/:locale)/register(.:format) users#new {:locale=>/en|nl/}
POST (/:locale)/register(.:format) users#create {:locale=>/en|nl/}
login GET (/:locale)/login(.:format) sessions#new {:locale=>/en|nl/}
POST (/:locale)/login(.:format) sessions#create {:locale=>/en|nl/}
logout DELETE (/:locale)/logout(.:format) sessions#destroy {:locale=>/en|nl/}
overview GET (/:locale)/user/overview(.:format) dashboard#index {:locale=>/en|nl/}
territories GET (/:locale)/admin/territories(.:format) territories#index {:locale=>/en|nl/}
POST (/:locale)/admin/territories(.:format) territories#create {:locale=>/en|nl/}
new_territory GET (/:locale)/admin/territories/new(.:format) territories#new {:locale=>/en|nl/}
edit_territory GET (/:locale)/admin/territories/:id/edit(.:format) territories#edit {:locale=>/en|nl/}
territory GET (/:locale)/admin/territories/:id(.:format) territories#show {:locale=>/en|nl/}
PATCH (/:locale)/admin/territories/:id(.:format) territories#update {:locale=>/en|nl/}
PUT (/:locale)/admin/territories/:id(.:format) territories#update {:locale=>/en|nl/}
DELETE (/:locale)/admin/territories/:id(.:format) territories#destroy {:locale=>/en|nl/}
GET /:locale(.:format) sessions#new
root GET / sessions#new
territories_controller.rb
class TerritoriesController < ApplicationController
def index
#territories = Territory.all.order(:name) #Must be changed to use pagination
end
def new
#territory = Territory.new
end
def import
end
def create
#territory = Territory.new(create_params)
if (!#territory.save)
render action: :create and return
end
render action :new
end
def show
end
def edit
#territory = Territory.find(edit_params)
end
def update
territory_params = update_params
#territory = Territory.find(territory_params[:id])
if (!#territory || !#territory.persisted?)
render index and return
end
#territory.update(territory_params[:territory])
end
def destroy
end
private
def create_params
params.require(:territory).permit(:name)
end
def edit_params
params.require(:id)
end
def update_params
id = params.require(:id)
territory = params.require(:territory).permit(:name)
{:id => id, :territory => territory}
end
end
territory_form.html.erb
<%= form_for(territory, remote: true) do |territory_form| %>
<p>
<%= territory_form.label :name %>
<%= territory_form.text_field :name %>
</p>
<%= territory_form.submit %>
<% end %>
Made it into a gist
def edit
#territory = Territory.find(edit_params)
end
Should just be
def edit
#territory = Territory.find(params[:id])
end

Updating a record with rails 4

I'm trying to update a record with an admin user with a "validate" button that changes the record's status from pending to confirmed. I've created a form, and the route to do so, however the controller is giving me trouble, I'm not sure what to code for it to update the specific record i click validate for.
Hours controller
def index
#allhours = HourLog.where(status:'Pending')
end
def update
#hour = HourLog.where(status:'Pending')
#hour.update(#hour.id, :status)
end
Hours/index.html.erb
<td><%=form_for(:hour_log, method: :put) do |f|%>
<%= f.hidden_field :status, :value => 'Confirmed' %>
<%= f.submit 'Validate'%>
<%end%>
</td>
Any help would be fantastic, thanks!
error:
NoMethodError in HoursController#update
undefined method `id' for #
I know something is wrond with the (#hour.id) section of the controller in the update def, but I don't know what to replace it with
edit: rake routes
Prefix Verb URI Pattern Controller#Action
root GET / welcome#index
signup GET /signup(.:format) users#new
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
GET /users(.:format) users#index
PUT /users(.:format) users#update
login GET /login(.:format) sessions#new
POST /login(.:format) sessions#create
logout DELETE /logout(.:format) sessions#destroy
dashboard GET /dashboard(.:format) hours#new
dashboard_hours GET /dashboard/hours(.:format) hours#index
hours PUT /hours(.:format) hours#update
GET /hours(.:format) hours#index
POST /hours(.:format) hours#create
new_hour GET /hours/new(.:format) hours#new
edit_hour GET /hours/:id/edit(.:format) hours#edit
hour GET /hours/:id(.:format) hours#show
PATCH /hours/:id(.:format) hours#update
PUT /hours/:id(.:format) hours#update
DELETE /hours/:id(.:format) hours#destroy
hours Controller
class HoursController < ApplicationController
before_action :require_user
before_action :require_admin, only: [:index]
def index
#allhours = HourLog.where(status:'pending')
end
def new
#hour = current_user.hour_logs.new
#entry = current_user.hour_logs.all
end
def edit
flash[:warning] = "Hash: #{params}"
end
def create
#hour = HourLog.new(hour_params)
#hour.user_id = current_user.id if current_user
#hour.status = 'pending'
if #hour.save
redirect_to '/dashboard'
end
end
private
def hour_params
params.require(:hour_log).permit(:assignment, :hours, :supervisor, :date)
end
def update_hour_params
params.require(:hour_log).permit(:status)
end
end
HourLog method
class HourLog < ActiveRecord::Base
belongs_to :user
end
I see this has an answer accepted, but I'd like to propose an alternative solution for anyone who may come along and find this question. Assumptions: The base page is an index with all pending items and the click is a simple state change. (A state toggle could be easily added to this solution.)
(I'm using the naming from the question.)
Using link_to as a message
A state change from 'Pending' to 'Confirmed' for a flag could be implemented by using the link_to to trigger the controller action to update this flag. Hash params may be passed via a link_to enabling simplified logic in the controller.
VIEW: Index.html.erb
<% #allhours.each do |hour| %>
<ul>
<li><%= hour.textdescriptionvar %> is an item pending approval.
<%= link_to(" Click to approve", edit_hour_path(hour, :status => "Confirmed"))
</li>
</ul>
<% end %>
CONTROLLER: HourLogsController
def edit
flash[:info] = "Hash: #{params}"
#hour = HourLog.find(params[:id])
end
def update
#hour = HourLog.find(params[:id])
#hour.update_attributes(hours_params)
if #hour.save
redirect_to #hour, :notice => "Successfully changed stat."
else
render 'index' # Any action here, index for example
end
end
private
def hours_params
params.require(:hour_log).permit(:status)
end
I would recommend a data: confirm message be added to the link_to,but I wanted to mimic the poster's situation as posted.
Rails spec for link_to here.
#hour = HourLog.where(status:'Pending') will return an ActiveRecord Relation, not a single record.
Try this:
#hour = HourLog.find_by(status: 'pending')
#hour.update_attribute :status, params[:hour_log][:status]
This method finds the first record with status ="pending" and updates that instead of the specific record.
You're going to want #hour.update params[:hour_log] instead because update_attribute doesn't run validations. and keep data in your database lowercase unless it's something written by a user. this link is useful http://www.davidverhasselt.com/set-attributes-in-activerecord/

Wicked, after delete action redirect_to

I have used wicked gem for my form. The thing is when user uploads photo they can see at the same page as ..../steps/picture. At Picture page user can destroy the picture. When user clicks I would like them to redirect_to steps/picture page but whatever I tried I get error on that. Boat and Picture associated but not nested routes.
here is my picture controller #destroy action;
def destroy
#picture = #boat.pictures.find(params[:id])
if #picture.destroy
######SOMETHING GOES HERE#########
flash[:notice] = "Successfully destroyed picture."
else
render json: { message: #picture.errors.full_messages.join(',') }
end
end
#boat_steps controller;
class BoatStepsController < ApplicationController
include Wicked::Wizard
before_action :logged_in_user
steps :model, :pricing, :description, :features, :picture
def show
#boat = current_user.boats.last
case step
when :picture
#picture = #boat.pictures.new
#pictures = #boat.pictures.all
end
render_wizard
end
def update
#boat = current_user.boats.last
#boat.update(boat_params)
case step
when :picture
#picture.update(picture_params)
end
render_wizard #boat
end
private
def finish_wizard_path
new_boat_picture_path(#boat, #picture)
end
def boat_params
params.require(:boat).permit(......)
end
def picture_params
params.require(:picture).permit(......)
end
end
EDIT 1:
>rake routes
Prefix Verb URI Pattern Controller#Action
update_years GET /boats/update_years(.:format) boats#update_years
update_models GET /boats/update_models(.:format) boats#update_models
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
boat_pictures GET /boats/:boat_id/pictures(.:format) pictures#index
POST /boats/:boat_id/pictures(.:format) pictures#create
new_boat_picture GET /boats/:boat_id/pictures/new(.:format) pictures#new
edit_boat_picture GET /boats/:boat_id/pictures/:id/edit(.:format) pictures#edit
boat_picture GET /boats/:boat_id/pictures/:id(.:format) pictures#show
PATCH /boats/:boat_id/pictures/:id(.:format) pictures#update
PUT /boats/:boat_id/pictures/:id(.:format) pictures#update
DELETE /boats/:boat_id/pictures/:id(.:format) pictures#destroy
boats GET /boats(.:format) boats#index
POST /boats(.:format) boats#create
new_boat GET /boats/new(.:format) boats#new
edit_boat GET /boats/:id/edit(.:format) boats#edit
boat GET /boats/:id(.:format) boats#show
PATCH /boats/:id(.:format) boats#update
PUT /boats/:id(.:format) boats#update
boat_steps GET /boat_steps(.:format) boat_steps#index
POST /boat_steps(.:format) boat_steps#create
new_boat_step GET /boat_steps/new(.:format) boat_steps#new
edit_boat_step GET /boat_steps/:id/edit(.:format) boat_steps#edit
boat_step GET /boat_steps/:id(.:format) boat_steps#show
PATCH /boat_steps/:id(.:format) boat_steps#update
PUT /boat_steps/:id(.:format) boat_steps#update
DELETE /boat_steps/:id(.:format) boat_steps#destroy
password_resets_new GET /password_resets/new(.:format) password_resets#new
password_resets_edit GET /password_resets/edit(.:format) password_resets#edit
profiles_edit GET /profiles/edit(.:format) profiles#edit
sessions_new GET /sessions/new(.:format) sessions#new
root GET / main#home
help GET /help(.:format) main#help
about GET /about(.:format) main#about
contact GET /contact(.:format) main#contact
signup GET /signup(.:format) users#new
login GET /login(.:format) sessions#new
POST /login(.:format) sessions#create
logout DELETE /logout(.:format) sessions#destroy
edit_account_activation GET /account_activations/:id/edit(.:format) account_activations#edit
password_resets POST /password_resets(.:format) password_resets#create
new_password_reset GET /password_resets/new(.:format) password_resets#new
edit_password_reset GET /password_resets/:id/edit(.:format) password_resets#edit
password_reset PATCH /password_resets/:id(.:format) password_resets#update
PUT /password_resets/:id(.:format) password_resets#update
EDIT:
Boat steps controller
class BoatStepsController < ApplicationController
include Wicked::Wizard
before_action :logged_in_user
steps :model, :pricing, :description, :features, :picture
def show
#boat = current_user.boats.last
case step
when :picture
#picture = #boat.pictures.new
#pictures = #boat.pictures.all
end
render_wizard
end
def update
#boat = current_user.boats.last
#boat.update(boat_params)
case step
when :picture
#picture.update(picture_params)
end
render_wizard #boat
end
private
def finish_wizard_path
new_boat_picture_path(#boat, #picture)
end
def boat_params
params.require(:boat).permit(:brand, :year, :model, :captained, :boat_type, :daily_price, :boat_length, :listing_tagline, :listing_description, :boat_category, :hull_material, :mast_material, :capacity, :sleeping_capacity, :private_staterooms, :fuel_type, :engine_horsepower, :fuel_capacity, :fuel_consumption, :draft)
end
def picture_params
params.require(:picture).permit(:name, :boat_id, :image)
end
end
On wicked wizards there are path helpers available on views that don't show on rake routes.
Try redirect_to wizard_path(:picture)
You can find more information about wicked helpers available to views here: https://github.com/schneems/wicked#quick-reference
These helpers will be available on views rendered using render_wizard. Outside of the wizard, the step is passed as the :id of the RESTful route.
To redirect to boat_steps/show on the picture step try redirect_to boat_step_path(id: :picture). The url generated should be /boat_steps/picture.

having trouble getting form to submit to the correct route

When submitting my form (_reply_form.html.erb) I get this error:
Routing Error
No route matches [POST] "/responses/replies/4"
Try running rake routes for more information on available routes.
This is how my architecture is set up: Offering has many Responses. Response has many Replies.
I know I need the form to submit to this route, but I can't get it to do that:
response_replies POST /responses/:response_id/replies(.:format) replies#create
_reply_form.html.erb:
<%= form_for(#reply, :url => response_reply_path([#response, #reply])) do |f| %>
<%= render 'common/form_errors', object: #reply %>
<%= f.label :body, "Your Reply" %>
<%= f.text_area(:body, :rows => 10, :class => "field span6") %>
<%= f.submit "Post Reply", :class => "block" %>
<% end %>
_response.html.erb:
<%= render 'replies/reply_form', {:response => #response, :reply => #reply} %>
offerings/show.html.erb:
<% if #offering.responses.any? %>
<%= render #offering.responses %>
<% else %>
<p>This offering has no responses yet.</p>
<% end %>
responses_controller.rb:
class ResponsesController < ApplicationController
before_filter :auth, only: [:create]
def show
#offering = Offering.new
#response = Response.new
#reply = Reply.new
end
def create
#offering = Offering.find(params[:offering_id])
# now that we have our offering we use it to
# build a response with it
#response = #offering.responses.build(params[:response])
# now we get the user who posted the response
#response.user = current_user
if #response.save
flash[:success] = 'your response has been posted!'
redirect_to #offering
else
#offering = Offering.find(params[:offering_id])
render 'offerings/show'
end
end
end
routes.rb:
resources :offerings, except: [:new] do
# makes it easier for us to display
# forms for responses on the offering show page
# allows us to have access to the
# offering that the response is associated to
resources :responses, only: [:create]
end
resources :responses, except: [:new] do
resources :replies, only: [:create]
end
rake routes produces this:
root / dashboard#index
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
need_applicants GET /needs/:need_id/applicants(.:format) applicants#index
POST /needs/:need_id/applicants(.:format) applicants#create
new_need_applicant GET /needs/:need_id/applicants/new(.:format) applicants#new
edit_need_applicant GET /needs/:need_id/applicants/:id/edit(.:format) applicants#edit
need_applicant GET /needs/:need_id/applicants/:id(.:format) applicants#show
PUT /needs/:need_id/applicants/:id(.:format) applicants#update
DELETE /needs/:need_id/applicants/:id(.:format) applicants#destroy
needs GET /needs(.:format) needs#index
POST /needs(.:format) needs#create
edit_need GET /needs/:id/edit(.:format) needs#edit
need GET /needs/:id(.:format) needs#show
PUT /needs/:id(.:format) needs#update
DELETE /needs/:id(.:format) needs#destroy
offering_responses POST /offerings/:offering_id/responses(.:format) responses#create
offerings GET /offerings(.:format) offerings#index
POST /offerings(.:format) offerings#create
edit_offering GET /offerings/:id/edit(.:format) offerings#edit
offering GET /offerings/:id(.:format) offerings#show
PUT /offerings/:id(.:format) offerings#update
DELETE /offerings/:id(.:format) offerings#destroy
response_replies POST /responses/:response_id/replies(.:format) replies#create
responses GET /responses(.:format) responses#index
POST /responses(.:format) responses#create
edit_response GET /responses/:id/edit(.:format) responses#edit
response GET /responses/:id(.:format) responses#show
PUT /responses/:id(.:format) responses#update
DELETE /responses/:id(.:format) responses#destroy
register /register(.:format) users#new
login /login(.:format) sessions#new
/offerings(.:format) offerings#index
/needs(.:format) needs#index
dashboard /dashboard(.:format) dashboard#index
contact /contact(.:format) contact#index
your_offerings /your_offerings(.:format) offerings#your_offerings
your_needs /your_needs(.:format) needs#your_needs
search /search(.:format) offerings#search
logout DELETE /logout(.:format) sessions#destroy
-- Original question
This should work for your form_for
<%= form_for([#response, #reply], :url => response_reply_path do |f| %>
-- Second part of your question route matches {:action=>"show", :controller=>"replies"}
I don't see anything wrong in your code, it's maybe in a part of your code you did not paste? Try to search for a link_to that would be corresponding
-- Bonus
Also you should not need to write your render with local variables, the controller instance variables #response and #reply will automatically be present in your partial
<%= render 'replies/reply_form' %>
# #response and #reply are automatically forwarded to all your views and partials
Off course if you are using response and reply in your partial you can rename them to #response and #reply respectively

Resources