Forum: Ruby on Rails Beginner problem with foreign keys

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
76ade6a3bc9aadb33df39c735caf46f7?d=identicon&s=25 Bill Clinton (bclinton)
on 2006-04-19 08:40
Hi, I've been trying to get this to work all night.  I've made some
progress by reading other posts, but I'm stuck now and can't figure out
what I am doing wrong.

I have two tables: application_users and user_types.  In my
application_users table I have a field named "user_type_id".  At first,
I thought if I set up the foreign key with the correct names, it would
automatically appear in my "new" form, but I got past that issue.

My application_user model looks like this:

class ApplicationUser < ActiveRecord::Base
        belongs_to :user_type
        validates_presence_of :first_name, :last_name, :user_type_id,
:login_name, :password
end

My user_type model looks like this:

class UserType < ActiveRecord::Base
        has_many :application_users
end

In my controller, my new method looks like this:

  def new
    @application_user = ApplicationUser.new
    @user_types = UserType.find_all
  end


And I modified the new.rhtml view to contain this select list:

<p><label for="application_user_user_type_id">User type</label><br/>
 <select name="application_user[user_type_id]">
 <% @user_types.each do |user_type| %>
 <option value="<%= user_type.id %>">
 <%= user_type.user_type %>
 </option>
 <% end %>
 </select>


The select list fills with the data from my user_types table, but when I
submit the form I get the famous "nil object" error under "NoMethodError
in Admin#create".  The extracted source shows my code for the select
list in new.rhtml, specifically the "<% @user_types.each do |user_type|
%>" line.

My create method in my controller looks correct to me:

  def create
    @application_user = ApplicationUser.new(params[:application_user])
    if @application_user.save
      flash[:notice] = 'User was successfully created.'
      redirect_to :action => 'list'
    else
      render :action => 'new'
    end
  end

I figured that there was some problem with my validation and it was
dying when it got sent back to the new form.  I commented out the
validation and the form worked correctly.  But if I put back the
validation, even just testing the presence of one field, and I don't
fill out that field, I get the same error.

It's obvious to me that the problem occurs when the application_user
object can't be saved, and it gets sent back to the form where the
user_types object is now nil.  But I don't understand why.  It seems
that when "application_user.save" fails, it goes to "render :action =>
'new'" where @user_types should be initialized.  The new method works
the first time I hit the form, why does it not work when it is called
from the create method?

Thanks for any help you can give me - this is driving me crazy.
3dd4b52a0946bd698b1d1635a46ea3a3?d=identicon&s=25 François Beausoleil (fbeausoleil)
on 2006-04-19 09:20
(Received via mailing list)
Hi !

2006/4/19, Bill Clinton <bclinton@rangercomputer.com>:
> It's obvious to me that the problem occurs when the application_user
> object can't be saved, and it gets sent back to the form where the
> user_types object is now nil.  But I don't understand why.  It seems
> that when "application_user.save" fails, it goes to "render :action =>
> 'new'" where @user_types should be initialized.  The new method works
> the first time I hit the form, why does it not work when it is called
> from the create method?

When you call render :action => :new, this only renders.  It doesn't
execute the logic in the #new method.

To resolve that problem, you have a few solutions:

1. Add a before_filter that will load @user_types when necessary
2. Copy/paste the line (big frown from the community)
3. Make the view find the user types itself (lesser frown)

Hope that helps !
76ade6a3bc9aadb33df39c735caf46f7?d=identicon&s=25 Bill Clinton (bclinton)
on 2006-04-20 00:28
François Beausoleil wrote:
> Hi !
>
> When you call render :action => :new, this only renders.  It doesn't
> execute the logic in the #new method.
>
> To resolve that problem, you have a few solutions:
>
> 1. Add a before_filter that will load @user_types when necessary
> 2. Copy/paste the line (big frown from the community)
> 3. Make the view find the user types itself (lesser frown)
>
> Hope that helps !

Thanks a lot.  The before_filter is exactly what I was looking for.  I
hadn't gotten that far in the book yet. ;)
This topic is locked and can not be replied to.