Why is id off by one or defined different in edit vs in update?

why is id off by one or defined different in edit vs in update? I will explain what I mean

I have a controller called Bottles and a model Bottle

My config\routes.rb file has the line- resources :bottles

I have this controller

class BottlesController < ApplicationController
  def index

  def show

  def edit
    #       :id==0
    # <ActionController::Parameters {"controller"=>"bottles", "action"=>"edit", "id"=>"0"} permitted: false>
# Bottle.all[0] gives <Bottle id: 1, name: "tod", size: 234,...>
    @bottle=Bottle.all[params[:id].to_i]   #:id==0

  def update
   # <ActionController::Parameters {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"zi2e5Vc3NTTgl89AoPvMxdlNLHGtv5pe6SmdJeVrBtZ5f1jsI9SKwtfj8KnS42p9sMazdTOK7VrVOu2V9E5GyQ==", "bottle"=>{"name"=>"todddd", "size"=>"234"}, "commit"=>"Save", "controller"=>"bottles", "action"=>"update", "id"=>"1"} permitted: false>
   # no form 
   render plain: "updated"

  def create
   # <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"68...jhfCfA==","bottle"=>{"name"=>"tod", "size"=>"334"},"commit"=>"Create", "controller"=>"bottles", "action"=>"create"} permitted: false>

   # byebug
   @bottle=Bottle.create params[:bottle].permit :name, :size

  def new

I have these views

C:\rubytest\testoby>type app\views\bottles\new.html.erb
<%= form_for @bottle do |f| %>
<%= f.text_field :name %>
<%= f.text_field :size %>
<%= f.submit “Create” %>
<% end %>

C:\rubytest\testoby>type app\views\bottles\edit.html.erb
<%= form_for @bottle do |f| %>
<%= f.text_field :name %>
<%= f.text_field :size %>
<%= f.submit “Save” %>
<% end %>

I went to and I made a bottle

name- tod
size- 234

I then go to

and I see the bottle there in the form

I then change tod to todd and click ‘save’

here’s the weird thing

I see the URL change to

but i’d expect it to change to

I’d expect the form to be submitted to /bottles/0 but it’s not, it’s submitted to /bottles/1

And the params have :id=1

So when it comes to my update, I have to write this line in the controller, subtracting 1 from the id


I can see that there is a difference of definition of :id that one could use… The id in the URL could be either A)The index in the array e.g. Bottle.all[params[:id]] (Which is what i’ve got for the edit action). or B) The id attribute of the object, (Which is what i’ve got for the update action @abottle=Bottle.all[params[:id].to_i-1]

One could say, it’s A, the URL. But then why should the update URL have an :id that is one up from the edit URL?


got it now, I was using :id as an index to the array.

by fixing the edit portion

the correct bottle is loaded… So now gives an error as it should as no bottle with that id exists as id starts from 1.

so now the update action is called with an id that matches the one specified in the edit url, since the bottle in the edit form also has the same id as the one in the edit url.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.