Unable to create associations

I have two tables, user & provider and I’m struggling to set up the
association between them.

A simplified table structure for the two is:

CREATE TABLE users (
id integer not null,
login string not null,
password string not null
)

CREATE TABLE providers (
id integer not null,
user_id integer not null,

)

and I’ve used the generater to create two modules, as follows (cut
down)

class User < ActiveRecord::Base
has_one :provider

def invoices_raised
provider.get_invoices
end

end

class Provider < ActiveRecord::Base
has_many :invoices
belongs_to :user

def get_invoices
invoices.find(:all)
end
end

I have a controller that calls invoices_raised :

class AccountController < ApplicationController
model :user

before_filter :get_invoices

def get_invoices
@user = User.find(@session[‘user’].id)

@invoices_raised = @user.invoices_raised

end

end

but inside the invoices_raised method I get the following error:

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

I thought that using belongs_to & has_one was supposed to implicitly
create a provider instance for me?


-S

Sports Photography in South Yorkshire & Derbyshire
http://www.stuartgrimshaw.co.uk

Stuart G. wrote:

class User < ActiveRecord::Base
has_one :provider

def invoices_raised
provider.get_invoices
end

end

What if you change “provider.get_invoices” to
“self.provider.get_invoices”?

Stuart G. wrote:

I have two tables, user & provider and I’m struggling to set up the
association between them.
{…}
class User < ActiveRecord::Base
has_one :provider

def invoices_raised
provider.get_invoices
end
end

but inside the invoices_raised method I get the following error:

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

I thought that using belongs_to & has_one was supposed to implicitly
create a provider instance for me?


-S

User.has_one :provider will create an accessor on your User class that
retrieves the Provider associated with a given user u (i.e. select *
from providers where providers.user_id=u.id). There’s not enough info in
your post to determine why this method is returning a nil for your User
instance; I would need to see the object that you are calling
get_invoices on and how it is created.

I would recommend brushing up on what the associations methods do
(belongs_to, has_many, etc), and you will likely discover the source of
the error

For example…

class Provider < ActiveRecord::Base
has_many :invoices
belongs_to :user

def get_invoices
invoices.find(:all)
end
end

Calling has_many :invoices actually creates an instance method
“invoices” in Provider that returns all Invoice objects associated with
your Provider instance. I’m guessing that this is what you hoped to
achieve with get_invoices.

I’m not sure what you’re expecting from your call “invoices.find(:all)”.
The invoices method returns all Invoice objects associated with your
Provider instance, and “find” is actually an ActiveRecord::Base class
method which will raise an error when you call it on a collection of
Invoices, which is what you’re doing here. find(:all) retrieves all
records from a particular table, and I’m guessing that’s not what you’re
trying to do here. If it is, you’ll want to call Invoice.find(:all)

I would recommend checking out the Rails documentation for associations:
http://api.rubyonrails.org/
(click on ActiveRecord::Associations::ClassMethods in the Class frame)

Hope this helps

  • Bryan

Bryan E. wrote:

User.has_one :provider will create an accessor on your User class that
retrieves the Provider associated with a given user u (i.e. select *
from providers where providers.user_id=u.id). There’s not enough info in
your post to determine why this method is returning a nil for your User
instance; I would need to see the object that you are calling
get_invoices on and how it is created.

get_invoices is called :

before_filter :get_invoices, :only => [:my_account]

Thanks for the reply Bryan, I know my understanding of asscociations is
poor, and I have read the docs again now (and tbh, I think I need to
again) but at that time in the morning, it seemed like the best thing
to do … :wink:

-S

Bryan D. wrote:

Stuart G. wrote:

class User < ActiveRecord::Base
has_one :provider

def invoices_raised
provider.get_invoices
end

end

What if you change “provider.get_invoices” to
“self.provider.get_invoices”?

If you omit the receiver, it defaults to self.

i.e. “provider.get_invoices” is interpreted as being equal to
“self.provider.get_invoices”

Here is a good link if you want to learn more about this or see some
examples:
http://www.rubycentral.com/book/tut_methods.html