Collection_select won't recover from form validation error


#1

I can’t quite put my finger on what’s happening here…I’m still trying
to grasp this framework. With the way my controller methods are
written, I thought that since I get a form validation error, it would
kick off the “new” action and gather up those collection_select
collections again (although I’m not even sure if that’s the
problem…nil.inject?). I can add and edit all day but it bombs if I
have a validation error. Much thanks in advance if anybody can shove me
in the right direction!

schema:
CREATE TABLE tickets (
id int(11) NOT NULL,
title varchar(255) default NULL,
details text,
status_id int(11) default NULL,
priority_id int(11) default NULL,
created_at datetime default NULL,
opened_at datetime default NULL,
closed_at datetime default NULL,
updated_at datetime default NULL,
last_activity_at datetime default NULL,
PRIMARY KEY (id),
KEY fk_ticket_status (status_id),
KEY fk_ticket_priority (priority_id),
CONSTRAINT fk_ticket_priority FOREIGN KEY (priority_id) REFERENCES
ticket_priorities (id),
CONSTRAINT fk_ticket_status FOREIGN KEY (status_id) REFERENCES
ticket_statuses (id)
);

CREATE TABLE ticket_statuses (
id int(11) NOT NULL,
status varchar(255) default NULL,
PRIMARY KEY (id)
);

CREATE TABLE ticket_priorities (
id int(11) NOT NULL,
rank int(11) default NULL,
priority varchar(255) default NULL,
PRIMARY KEY (id)
);

Ticket model:
belongs_to :ticket_status, :foreign_key => “status_id”
belongs_to :ticket_priority, :foreign_key => “priority_id”

validates_presence_of :title, :details, :status_id, :priority_id

controller:

def new
@ticket = Ticket.new
@ticket_status = TicketStatus.find_all
@ticket_priority = TicketPriority.find_all
end

def create
@ticket = Ticket.new(params[:ticket])
@ticket.opened_at = DateTime.now
@ticket.closed_at = nil
@ticket.last_activity_at = DateTime.now
if @ticket.save
flash[:success] = ‘Ticket was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

error:
NoMethodError in Ticket#create

Showing app/views/ticket/_form.rhtml where line #11 raised:
You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.inject

Extracted source (around line #11):

8: <%= text_area ‘ticket’, ‘details’, {:style => “width: 325px”} %>


9:
10:

Status

11: <%= collection_select(“ticket”, “status_id”, @ticket_status, “id”,
“status”, {:prompt => “Select status…”}, {:style => “width: 150px”})
%>


12:
13:

Priority

14: <%= collection_select(“ticket”, “priority_id”, @ticket_priority,
“id”, “priority”, {:prompt => “Select priority…”}, {:style => “width:
150px”}) %>


#2

Try changing this:

collection_select(“ticket”, “priority_id”, @ticket_priority,
“id”, “priority”, {:prompt => “Select priority…”}

to this:

collection_select(@ticket, :priority_id, @ticket_priority,
:id, :priority, {:prompt => “Select priority…”}

-Paul


#3

Paul C. wrote:

-Paul


Posted via http://www.ruby-forum.com/.

Hmm…now it won’t even render the form.

NameError in Ticket#new

Showing app/views/ticket/_form.rhtml where line #11 raised:

`@#Ticket:0xb75ee748’ is not allowed as an instance variable name

Extracted source (around line #11):

8: <%= text_area ‘ticket’, ‘details’, {:style => “width: 325px”}
%>


9:
10:

Status

11: <%= collection_select(@ticket, :status_id, @ticket_status, :id,
:status, {:prompt => “Select status…”}, {:style => “width: 150px”})
%>


12:
13:

Priority

14: <%= collection_select(@ticket, :priority_id, @ticket_priority, :id,
:priority, {:prompt => “Select priority…”}, {:style => “width:
150px”}) %>


#4

Well, I found one solution at least. Something must be going on behind
the scenes that’s not really obvious.

First, I tried this combination:
controller:
def new
@ticket = Ticket.new
@ticket_status = TicketStatus.find_all.collect {|s| [ s.status, s.id
] }
@ticket_priority = TicketPriority.find_all.collect {|p| [ p.priority,
p.id ] }
end

view:

Status
<%= select('ticket', 'status_id', @ticket_status, {:prompt => "Select status..."}, {:style => "width: 150px"}) %>

Priority
<%= select('ticket', 'priority_id', @ticket_priority, {:prompt => "Select priority..."}, {:style => "width: 150px"}) %>

And that still didn’t work. So then I removed both of the collections
from the controller and did it all in the view like this and it works:

Status
<%= select('ticket', 'status_id', TicketStatus.find_all.collect {|s| [ s.status, s.id ] }, { :include_blank => true }, {:style => "width: 150px"}) %>

Priority
<%= select('ticket', 'priority_id', TicketPriority.find_all.collect {|p| [ p.priority, p.id ] }, { :include_blank => true }, {:style => "width: 150px"}) %>

I’m also not using the collection_select anymore but I guess when I
have a form validation error, it must do it’s own thing somehow and
clears out those two .find_all collections. It just doesn’t feel right
to select data from the view like that…I’d really be interested to
know what happens when the validation fails and how I could put those
.find_all’s in the controller and not the view…