I have an app where I know
def new
respond_to do |format|
format.html { new_or_edit }
format.js {
@category = Category.new
}
end
end
is being called when I click a link.
This leads to new_or_edit being called (defined in the same file).
def new_or_edit
@categories = Category.find(:all)
@category = Category.find(params[:id])
@category.attributes = params[:category]
if request.post?
respond_to do |format|
format.html { save_category }
format.js do
@category.save
@article = Article.new
@article.categories << @category
return render(:partial => 'admin/content/categories')
end
end
return
end
render 'new'
end
After some tests, I find that the each execution stops at
@category = Category.find(params[:id])
with the error “Couldn’t find Category without an ID”. Params doesn’t have an :id hash when I printed it out. Is this because I have to save it into the database before the default :id field is created?
What you are doing wrong is trying to unify two inherently different actions: new and edit.
params is a hash of parameters you get from the client.
When you create a new object,
params[:id]is left blank since the id attribute of a newly created object is the responsibility of the server, not the client.When you edit an existing object,
params[:id]is not blank since the object already exists in the database and has an id. The meaning ofparams[:id]here is “Please edit object with id param[:id] using these attributes”.After explaining this, when you create a new object this line:
Fails since
params[:id]is empty.