Related Models

I am still somewhat new to rails and I am not getting the results I am
expecting with my models… perhapse I do not understand something, or
just didn’t set something up right.

I have three models:

class Coordinator < ActiveRecord::Base
belongs_to :county
belongs_to :state
end

class State < ActiveRecord::Base
has_many :counties
has_many :coordinators, :through => :counties
accepts_nested_attributes_for :counties, :coordinators
end

class County < ActiveRecord::Base
belongs_to :state
has_one :coordinator
accepts_nested_attributes_for :coordinator
scope :returncounty, lambda {|state| where(:state_id => state)}
end

When I try and do something like this in my view

<% @states.each do |state| %>
<% state.counties.each do |county| %>

<%= county.name %> <%= county.coordinator.name %>

<% end %> <% end %>

I am getting:this error. I have tried several variations on this
theme… so I feel like I am stuck in my understanding of how rails
associations work. Can someone point me in the right direction?
undefined method `name’ for “#<Coordinator:
0x00000003a83128>”:Coordinator

On 26 May 2011 07:07, Aaron M. [email protected] wrote:

I am getting:this error. I have tried several variations on this
theme… so I feel like I am stuck in my understanding of how rails
associations work. Can someone point me in the right direction?
undefined method `name’ for “#<Coordinator:
0x00000003a83128>”:Coordinator

That’s a fairly straightforward, self-explanatory error, that’s got
nothing to do with associations.
It’s telling you that Coordinator has no method “name”. Have you
created and run a migration to add a field called “name” to that
table? Can you check in your DB management tool to check the field is
there. Can you open a console and execute “Coordinator.new” (or just
“Coordinator”) and see the list of available attributes/field names.

Let us know the result.
Regards,

On 26 May 2011 07:07, Aaron M. [email protected] wrote:

scope :returncounty, lambda {|state| where(:state_id => state)}
end

Probably not associated with your problem but there is something not
right above, you have two routes to coordinator from state. You have
coordinator belongs to state (implying coordinator has a state_id
column) and so you should also have state has many coordinators (which
you have not specified). You also have coordinator belongs to county
and county has one coordinator, but then in state you also have state
belongs_to county and state has_many coordinators through counties.
So when you say @state.coordinators it will get the coordinators from
the counties, in which case you should not have coordinator belongs to
state.

Colin

Woops in all my changes I put name instead of firstname on my
coordinators… This is now correct but the original issue is still
there… which is when I try and call state.county.name or
coordinator.state.name or county.state.name.

I am quite sure that county.name exists and that state.name exists.

I ran some commands in the console, here is what I get:

examplestate = State.find(1)
=> #<State id: 1, name: “Alabama”, abreviation: “AL”, created_at:
“2011-04-04 16:32:08”, updated_at: “2011-04-04 16:32:08”>

examplestate.name
=> “Alabama”

examplecounties = examplestate.counties
=> [#<County id: 3, name: “Baldwin County”, state_id: 1, created_at:
“2011-04-04 16:32:32”, updated_at: “2011-04-04 16:32:32”>, #<County
id: 4, name: “Cherokee County”, state_id: 1, created_at: “2011-04-04
16:32:32”, updated_at: “2011-04-04 16:32:32”>, #<County id: 5, name:
“Chilton County”, state_id: 1, created_at: “2011-04-04 16:32:33”,
updated_at: “2011-04-04 16:32:33”>, #<County id: 6, name: “Clarke
County”, state_id: 1, created_at: “2011-04-04 16:32:33”, updated_at:
“2011-04-04 16:32:33”>, #<County id: 7, name: “Colbert County”,
state_id: 1, created_at: “2011-04-04 16:32:33”, updated_at:
“2011-04-04 16:32:33”>, #<County id: 8, name: “Crenshaw County”,
state_id: 1, created_at: “2011-04-04 16:32:33”, updated_at:
“2011-04-04 16:32:33”>, #<County id: 9, name: “Cullman County”,
state_id: 1, created_at: “2011-04-04 16:32:33”, updated_at:
“2011-04-04 16:32:33”>, #<County id: 10, name: “DeKalb County”,
state_id: 1, created_at: “2011-04-04 16:32:33”, updated_at:
“2011-04-04 16:32:33”>,etc… etc…

examplecounties.each do |county|
puts county.coordinator.firstname
end

Jessica
Ron
P. Dale
Gerry
Garry
Tami
Samuel
etc. etc.

So when I call a coordinators firstname from a county, from a state…
it seems to work… but then when I try that in the view for instance:

My state controller calls @state.all

and in the state index view I have:

<% @states.each do |state| %>
<%= state.name %>
<% state.counties.each do |county| %>

<%= county.coordinator.firstname %>

<% end %> <% end %>

I get this error:
undefined method `firstname’ for nil:NilClass

On 26 May 2011 15:09, Aaron M. [email protected] wrote:

This is now correct but the original issue is still
there… which is when I try and call state.county.name or
coordinator.state.name or county.state.name.

I get this error:
undefined method `firstname’ for nil:NilClass

That’s a different error to what you had before.
That’s telling you that the thing you’re trying to call “.firstname”
on is nil. ie: there is no coordinator for the given county.

You can guard against this error any number of ways, an easy one being:
<%= county.coordinator.firstname if county.coordinator %>

Great… I knew it had to be something so simple… You helped me get
past the brick wall!

I had not even considered that nearly 70% of my counties have no
coordinator!!! DOH!

thanks for your help

As another example I can also put in the same view:

<% @states.each do |state| %>
<% state.coordinators.each do |coordinator| %>

<%= coordinator.county.name %>

<% end %> <% end %>

and I get
undefined method `name’ for nil:NilClass