Has_one, belongs_to - I am just not getting it

Let me preface by saying i’m a total noob at ruby/rails. :slight_smile:
For some reason, I am just not grasping the concept of has_one &
belongs_to…

I’m working on a project that includes user authentication, and 3
different types of user profiles.

User profiles are either “fan”, “band”, or “venue” objects, and user
logins are “user” objects.

Just working with the “fan” profiles now.

I have the following tables:
table fans:
id
name
url

(etc)

user_id (foreign key)

table users:
id
login
hashed_password
email
salt
created_at

In User model:
class User < ActiveRecord::Base
has_one :fan

In Fan model:
class Fan < ActiveRecord::Base
belongs_to :user

in user_controller.rb:
def signup
@user = User.new(@params[:user])
if request.post?
if @user.save
session[:user] = User.authenticate(@user.login,
@user.password)
flash[:message] = “Signup successful”
redirect_to :controller => ‘fan’, :action => “new”
else
flash[:warning] = “Signup unsuccessful”
end
end
end

In fan_controller.rb:
def new
@fan = Fan.new
end

def create
@fan = Fan.new(params[:id])
@user.fan << @fan
if @fan.save
flash[:notice] = ‘Your Fan Profile was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

The goal is, when a new user signs up, after creating their login info,
they get to create their “fan” profile, and when it is saved, the
profile is saved in the fans table, with the appropriate user_id
assigned to it.

As I currently have it, the user signup works, then takes me to the new
profile form, but when I try to save, I get:
NoMethodError in FanController#create

You have a nil object when you didn’t expect it!
The error occured while evaluating nil.fan

RAILS_ROOT: script/…/config/…
Application Trace | Framework Trace | Full Trace

#{RAILS_ROOT}/app/controllers/fan_controller.rb:28:in `create’

line 28 is ‘@user.fan << @fan

i’ve tried @user.fan = @fan, that doesn’t work…

I keep reading and reading about this, and I just can’t seem to get a
handle on it yet. I’m in dire need of help!

much obliged,
Chad

def create
@fan = Fan.new(params[:id])
@user.fan << @fan
if @fan.save
flash[:notice] = ‘Your Fan Profile was successfully created.’
redirect_to :action => ‘list’
else
render :action => ‘new’
end
end

you didn’t define @user.

def create
@user = User.find(…whicheveroneyouwant…) OR
@user = User.find(params[:id]) OR
@user = User.find_by_some_column(value) OR

@fan = Fan.new…

end

i reccomended you should do some tutorial to help you out; have you
tried four days on rails? or the pragmatic store self-tutorial? these
are great books and will give you a great base to jump off of.

anyway, i hope that helps you out.

On Thu, 6 Jul 2006, Chad Wells wrote:

 redirect_to :action => 'list'

As I currently have it, the user signup works, then takes me to the new
profile form, but when I try to save, I get:
NoMethodError in FanController#create

You have a nil object when you didn’t expect it!
The error occured while evaluating nil.fan

Instance variables only survive for the duration of one action, which
may include a “render” but not a “redirect” (that’s a new action). So
in create, you never initialize @user – so it’s nil.

I have a feeling that what you really want is something like:

def create
@user = User.find(params[:id])
@fan = Fan.create(params[:fan])
@user.fan = @fan

etc.

Doing Fan.new(params[:id]) doesn’t make sense, since if it’s new, it
will get assigned an id automatically, and if you’re looking it up by
id, you’d use “find”.

David


“To fully realize the potential of Rails, it’s crucial that you take
the time to fully understand Ruby–and with “Ruby for Rails” David
has provided just what you need to help you achieve that goal.”
– DAVID HEINEMEIER HANSSON, in the foreword to RUBY FOR RAILS.
Complete foreword & sample chapters at http://www.manning.com/black!

unknown wrote:

Instance variables only survive for the duration of one action, which
may include a “render” but not a “redirect” (that’s a new action). So
in create, you never initialize @user – so it’s nil.

I think this is my main problem! I guess I just didn’t realize this
fact. This makes sense as to why I was having so many other little
problems.

Thank you so much!

Another question, is there a way to keep an instance variable alive for
a total session, instead of having to intialize it over and over?

On Jul 6, 2006, at 6:16 AM, Chad Wells wrote:

Another question, is there a way to keep an instance variable alive
for
a total session, instead of having to intialize it over and over?

That’s what session is for:

session[:key] = @blah

and in a subsequent request:

@blah = session[:key]

On caveat: Don’t store an ActiveRecord in the session. Instead store
it’s
id and refetch it the next time, unless it’s you absolutely KNOW that it
won’t change.


– Tom M.