I have an application that has a one to many relationship with downtowns and properties. What i've been having trouble with is creating new properties from the downtowns. I keep getting the error that I used as the title for this question.
I have a hunch that the problem is in my form, (which i'm using the simple form gem). I'm able to go to my new
page, fill out the form, and then when I hit submit, I get this error.
I'll display my form file first. (I've had trouble understanding simple form's docs, and that's why i think this is where the problem is)
= simple_form_for (@property), method: 'POST', url: new_downtown_property_path do |f|
= f.input :name
= f.input :last_remodel
= f.input :original_construction_year
My routes file
resources :downtowns do
resources :properties
end
My downtown controller
def show
@properties = Property.where(downtown: @downtown_id)
end
def new
@downtown = Downtown.new
end
def create
@downtown = Downtown.create(downtown_params)
if @downtown.save
redirect_to @downtown
else
render 'new'
end
end
def downtown_params
params.require(:downtown).permit(:name, :city)
end
and my properties controller
def new
@property = Property.new
end
def create
@downtown = property.find(id)
@property = Property.create(params[:property_params])
@property.downtown_id = @downtown.id
if @property.save
redirect_to @property
else
render 'new'
end
end
def show
end
= simple_form_for([@downtown, @property]) do |f|
= f.input :name
= f.input :last_remodel
= f.input :original_construction_year
Just pass an array to look up the nested route with the polymorphic route helpers. This will correctly use downtown_properties_path
as the action. In Rails you always create resources by posting to the collection path (/downtowns/1/properties
). The new route just renders a form. You don't need to specify the method as Rails detects if the model has been persisted and sets the method to POST or PATCH accordingly.
You should also never add a space between the method name and the parens surrounding the argument list in Ruby:
def add(a,b)
a + b
end
add (1, 2) # syntax error
add (1), 2 # this is what actually happens
Ruby behaves very differently then for example JS here since parens are optional for method calls.
Your controller is also completely off. A nested resource controller should look something like.
class PropertiesController < ApplicationController
before_action :set_downtown
before_action :set_property, only: [:show, :edit, :update, :destroy]
# GET /downtowns/1/properties/new
def new
@property = @downtown.properties.new
end
# POST /downtowns/1/properties
def create
@property = @downtown.properties.new(property_params)
if @property.save
redirect_to @property
else
render :new
end
end
# ...
private
def set_downtown
@downtown = Downtown.includes(:properties).find(params[:downtown_id])
end
def set_propery
@property = Property.find(params[:id])
end
def property_params
params.require(:downtown)
.permit(:name, :city)
end
# ...
end