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


#1

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

  def update
   # http://127.0.0.1:3000/bottles/1
   
   # <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 
   @abottle=Bottle.all[params[:id].to_i-1]
   @abottle.name=params[:bottle][:name]
   @abottle.size=params[:bottle][:size]
   @abottle.save
   render plain: "updated"
  end

  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
  end

  def new
   @bottle=Bottle.new
  end
  
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 edit URL?

Thanks


#2

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

by fixing the edit portion
@abottle=Bottle.all.find(params[:id].to_i)

the correct bottle is loaded… So 127.0.0.1:3000/bottles/0/edit 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.


#3

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