Question

Ruby 1.9.2p290

Rails 3.1.0

I built my site from scaffolding and am trying to change my routes, so, instead of using the :id, I can use :gameNumber.

In my controller I changed

from

@ticket = Ticket.find(params[:id])

to

@ticket = Ticket.find_by_gameNumber(params[:id])

In my views I changed

from

ticket

to

ticket_path(ticket.gameNumber)

The problem I'm having is when I'm trying to update, I get a nil error. I know the problem is because the update button is using the :id and not the :gameNumber, I'm just not sure how to fix it. Here is the relevant code relating to the problem.

Controller

def update
  @ticket = Ticket.find_by_gameNumber(params[:id])

  respond_to do |format|
    if @ticket.update_attributes(params[:ticket])
      format.html { redirect_to ticket_path(@ticket.gameNumber), notice: 'Ticket was successfully updated.' }
      format.json { head :ok }
    else
      format.html { render action: "edit" }
      format.json { render json: @ticket.errors, status: :unprocessable_entity }
    end
   end
end

Form

<%= form_for(@ticket) do |f| %>

If anyone can point me to a link that can explain the problem, help explain the problem, provide a solution, or a better way to do this, I would really appreciate it.

Thanks.

Update:

Here is the error:

NoMethodError in TicketsController#update

You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.update_attributes

Rails.root: C:/home/workspace/App

Application Trace

app/controllers/tickets_controller.rb:65:in block in update' app/controllers/tickets_controller.rb:64:inupdate'

Request

Parameters:

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"4ft2LU5CRcV+qV8ipjBm23TTBrXlmHjA042SpSZOkMc=",
 "ticket"=>{"gameNumber"=>"1114",
 "gameName"=>"Fun"
 "isClosing"=>"0",
 "isActive"=>"1"},
 "commit"=>"Update Ticket",
 "key"=>:gameNumber,
 "id"=>"220"}

Would you like the Framework Trace and Full Trace too?

Update 2:

If I add the following to my model:

def to_param
   gameNumber
end

I get the following errors.

NoMethodError in Tickets#edit

Showing C:/home/workspace/App/app/views/tickets/_form.html.erb where line #1 raised:

undefined method `split' for 1114:Fixnum

Extracted source (around line #1):

1: <%= form_for(@ticket) do |f| %>
2:   <% if @ticket.errors.any? %>
3:     <div id="error_explanation">
4:       <h2><%= pluralize(@ticket.errors.count, "error") %> prohibited this ticket from being saved:</h2>

Trace of template inclusion: app/views/tickets/edit.html.erb

Rails.root: C:/home/workspace/App

Application Trace:

app/views/tickets/_form.html.erb:1:in `_app_views_tickets__form_html_erb__464096833_36793764'
app/views/tickets/edit.html.erb:3:in `_app_views_tickets_edit_html_erb__750875298_37634784'

Request

Parameters:

{"key"=>:gameNumber,
 "id"=>"1114"}
Was it helpful?

Solution

Much as you needed to change calls to ticket_path to use gameNumber instead of id, you'll need to change your form_for call. By default when form_for is called for an existing record the url it posts to will be ticket_path(ticket). You can override that by passing a :url option.

Instead of all this, you might want to consider doing

class Ticket < ActievRecord::Base
  def to_param
    gameNumber.to_s
  end
end

This should make ticket_path(ticket) or form_for(ticket) use gameNumber in the url without you having to go and change every invocation of ticket_path.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top