Validates causes NoMethodError

I am trying to validate the uniqueness of a field:

class Department < ActiveRecord::Base
belongs_to :company
belongs_to :region
has_many :employees
validates_uniqueness_of :dept_name
end

When I run it, I get this error message:

NoMethodError in Department#create

Showing app/views/department/_form.rhtml where line #34 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.each

Extracted source (around line #34):

31: <% if @page_title == “New Department” %>
32:
33: Select One
34: <% @companies.each do |company| %>
35:
36: <%= company.comp_name %>
37:

However, if I take validates_uniqueness_of off, i.e.:

class Department < ActiveRecord::Base
belongs_to :company
belongs_to :region
has_many :employees
#validates_uniqueness_of :dept_name
end

everything works just fine. What am I doing wrong?

George

Hi –

On Sun, 24 Sep 2006, simplydope wrote:

When I run it, I get this error message:

class Department < ActiveRecord::Base
belongs_to :company
belongs_to :region
has_many :employees
#validates_uniqueness_of :dept_name
end

everything works just fine. What am I doing wrong?

I don’t know, but I have a couple of follow-up questions/suggestions:

Is there anything in the stack trace that might help (including
anything indicating a problem with validation itself)?

Try doing stuff in the application console. That might be a good way
to walk through some collection-finding mini-scenarios.

If it remains a problem, post your Company model code and the view for
that action.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

unknown wrote:

Hi –

On Sun, 24 Sep 2006, simplydope wrote:

When I run it, I get this error message:

class Department < ActiveRecord::Base
belongs_to :company
belongs_to :region
has_many :employees
#validates_uniqueness_of :dept_name
end

everything works just fine. What am I doing wrong?

I don’t know, but I have a couple of follow-up questions/suggestions:

Is there anything in the stack trace that might help (including
anything indicating a problem with validation itself)?

Try doing stuff in the application console. That might be a good way
to walk through some collection-finding mini-scenarios.

If it remains a problem, post your Company model code and the view for
that action.

David


David A. Black | [email protected]
Author of “Ruby for Rails” [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB’s Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

Not exactly sure what I can “do” in the colsole. Pretty new to RoR.
But here are model and view:

class Company < ActiveRecord::Base
has_many :departments
has_many :employees
validates_presence_of :comp_name
validates_uniqueness_of :comp_name
end


new.html (department)

<%
@page_title = “New Department”
%>

<%= start_form_tag :action => ‘create’ %>
<%= render :partial => ‘form’ %>

<%= end_form_tag %>


_form.rhtml (department)

<%= error_messages_for ‘department’ %>

<%=@page_title %>
Dept. #: <%= text_field 'department', 'dept_num' %>
Dept. Name: <%= text_field 'department', 'dept_name' %>
Company: <% if @page_title == "New Department" %> Select One <% @companies.each do |company| %> <%= company.comp_name %> <% end %> <% else %> <% @companies.each do |company| %> > <%= company.comp_name %> <% end %> <% end %>
Region: <% if @page_title == "Edit Department" %> <% @regions.each do |region| %> > <%= region.region %> <% end %> <% else %>
   <select name="department[region_id]">
     <% @regions.each do |region| %>
       <option value="<%= region.id %>">
         <%= region.region %>
       </option>
     <% end %>
   </select>
   <% end %>
 </td>
Address 1: <%= text_field 'department', 'address1' %>
Address 2: <%= text_field 'department', 'address2' %>
City: <%= text_field 'department', 'city' %>
State: <%= text_field 'department', 'state' %>
Zip Code: <%= text_field 'department', 'zip_code' %>
Frontline
<%= link_to 'Back', :action => 'list' %>

Thanks for the help

George

On 24 Sep 2006, at 21:13, simplydope wrote:

NoMethodError in Department#create

Showing app/views/department/_form.rhtml where line #34 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.each

34: <% @companies.each do |company| %>

Seems to me that you don’t have an @companies instance variable in
whichever view includes _form. So is there a path in your department
controller that can use the _form, without first initialising
@companies?

Paul

Paul L. wrote:

On 24 Sep 2006, at 21:13, simplydope wrote:

NoMethodError in Department#create

Showing app/views/department/_form.rhtml where line #34 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.each

34: <% @companies.each do |company| %>

Seems to me that you don’t have an @companies instance variable in
whichever view includes _form. So is there a path in your department
controller that can use the _form, without first initialising
@companies?

Paul


No exactly sure what you’re asking…but here is my
department_controller.rb

class DepartmentController < ApplicationController

def index
list
render :action => ‘list’
end

GETs should be safe (see

URIs, Addressability, and the use of HTTP GET and POST)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :list }

def list
@department_pages, @departments = paginate :departments, :per_page
=> 20,
:conditions => “deleted_yn = 0”, :order_by => “dept_name”
end

def show
@department = Department.find(params[:id])
end

def new
@department = Department.new
@companies = Company.find(:all, :conditions => “deleted_yn = 0”,
:order => “comp_name”)
@regions = Region.find(:all, :conditions => “deleted_yn = 0”, :order
=> “region”)
end

def create
@department = Department.new(params[:department])
if @department.save
flash[:notice] = ‘Department was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

def edit
@department = Department.find(params[:id])
@companies = Company.find_all
@regions = Region.find_all
end

def update
@department = Department.find(params[:id])
if @department.update_attributes(params[:department])
flash[:notice] = ‘Department was successfully updated.’
redirect_to :action => ‘list’
else
render :action => ‘edit’
end
end

def destroy
@department = Department.find(params[:id])
Department.update(params[:id], {:deleted_yn => 1})
redirect_to :action => ‘list’
end
end

Thanks,

George

On 25 Sep 2006, at 00:23, George wrote:

Paul L. wrote:

On 24 Sep 2006, at 21:13, simplydope wrote:

NoMethodError in Department#create

Note that the error is in create.

controller that can use the _form, without first initialising
@companies?

0", :order
=> “region”)
end

new initialises @companies.

def create
@department = Department.new(params[:department])
if @department.save
flash[:notice] = ‘Department was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

But create doesn’t.

The thought about model associations causing the problem is a red
herring; copy your '@companies = ’ line into create from new, and it
should work.

Paul

Paul L. wrote:

On 25 Sep 2006, at 00:23, George wrote:

Paul L. wrote:

On 24 Sep 2006, at 21:13, simplydope wrote:

NoMethodError in Department#create

Note that the error is in create.

controller that can use the _form, without first initialising
@companies?

0", :order
=> “region”)
end

new initialises @companies.

def create
@department = Department.new(params[:department])
if @department.save
flash[:notice] = ‘Department was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

But create doesn’t.

The thought about model associations causing the problem is a red
herring; copy your '@companies = ’ line into create from new, and it
should work.

Paul

Thanks. It worked. Here’s the result, for those that have this problem
in the future.

def new
@department = Department.new
@companies = Company.find(:all, :conditions => “deleted_yn = 0”,
:order => “comp_name”)
@regions = Region.find(:all, :conditions => “deleted_yn = 0”, :order
=> “region”)
end

def create
@department = Department.new(params[:department])
@companies = Company.find(:all, :conditions => “deleted_yn = 0”,
:order => “comp_name”)
@regions = Region.find(:all, :conditions => “deleted_yn = 0”, :order
=> “region”)
# I could use this for deleted_yn
# @department.deleted_yn = 0
if @department.save
flash[:notice] = ‘Department was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end