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

end

def show

end

def edit

http://127.0.0.1:3000/bottles/0/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

end

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 %>

C:\rubytest\testoby>

I went to http://127.0.0.1:3000/bottles/new and I made a bottle

name- tod
size- 234

I then go to http://127.0.0.1:3000/bottles/0/edit

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

http://127.0.0.1:3000/bottles/1

but i’d expect it to change to

http://127.0.0.1:3000/bottles/0

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

@abottle=Bottle.all[params[:id].to_i-1]

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 ID in the edit URL?

Thanks

Where in the world are you getting this id of 0 ? What database
are you using? Every DB I've worked with starts an auto-increment
sequence with a positive (e.g. 1 or higher) number...

Thanks, well spotted, that was my mistake / the bug in my program.

The id of the object was 1. But I was going to /bottles/0/edit Then in the edit action I was using that number (0), to identify the object, because I was using that number as an index to the array. Bottles.all[0] So the data from the first bottle was going into the form.

Then, when I click the button to submit the form, it posts to /bottles/1 because it was using the id of @bottle

So I need my edit action to treat the number in the url (the id), as an id and not as an index to an array.

So , in the edit action, I could use @bottle=Bottle.find(…), and then pass in the id to the find method.

So the id in the edit url will then match the id of the object, and then there’s no change in id when the form is submitted.

Thanks

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
  end

  def show
  end

  def edit
    # http://127.0.0.1:3000/bottles/0/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

Your error is on these lines. When working on arrays, the first item in an
array has an index of 0. So you'd think that

bottles = Bottle.all
bottles[0].id == 1
bottles[1].id == 2

and so on.

In the edit action, you should be getting the id of the bottle so you can
find the bottle using

Bottle.find(params[:id])

  end

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 %>
C:\rubytest\testoby>

For some weird reason, @bottle here should be defined in the edit action in
your controller. But your
edit action is empty.

I went to http://127.0.0.1:3000/bottles/new and I made a bottle

name- tod
size- 234

I then go to http://127.0.0.1:3000/bottles/0/edit

Don't use the index as the number but the actual id saved in the database

@bottle=Bottle.all[params[:id].to_i] #:id==0

Your error is on these lines. …

Yeah I got it now, thanks, I fixed all my actions

In the edit action, you should be getting the id of the bottle so you can find the bottle using

Bottle.find(params[:id])

yeah

For some weird reason, @bottle here should be defined in the edit action in your controller. But your

edit action is empty.

actually my edit action wasn’t empty, it had one line. @bottle=Bottle.all[params[:id].to_i] But I have fixed that now , to a line that uses the .find method Bottle.find(params[:id]) and i’ve fixed the other actions too, like update.

Thanks