has_many :through=>one

Hi everyone.

I am facing a problem with has_many :through with the following model
relations:

class User < AR
  has_one :profile
  has_many :files, :through => :profile
end

class Profile < AR
  belongs_to :user
  has_many :files
end

class File < AR
  belongs_to :profile
end

While the call user.files succeeds with no problem, the following
assignment fails.

f = File.new
u = User.first
u.files << f # FAILURE HERE!

Rails spits out a
ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection
exception.

Can anyone shed some light on this ?

Cheers,

sergioL

Hi everyone.

I am facing a problem with has_many :through with the following model
relations:

class User < AR
has_one :profile
has_many :files, :through => :profile
end

class Profile < AR
belongs_to :user
has_many :files
end

class File < AR
belongs_to :profile
end

I think you might want to reconsider using the name File as this is
already a class in Ruby. Whether this is the cause of your problem I
don't know, but I would try that first.

Colin

Exactly what the error says - you can't have a has_many through a has_one

Either chain the method calls to your user's profiles files:

  user = User.first
  files = user.profile.files

...or create a delegate method in user to return the profile's files:

  class User < AR
    has_one :profile
    def files
      self.profile ? self.profile.files : []
    end
  end

HTH

oh yeah... and try to avoid reserved words too :slight_smile:

yebbut... encapsulation *is* a "good thing"... and you wouldn't want
to encourage the OP to denormalise for the sake of it. It is nice to
have classes responsible for their own stuff. I like to keep the User
model of my own for just authentication/essential info, and delegate
addresses, telephones, hobbies, etc, to their own classes... horses
for courses :slight_smile:

I agree about the encapsulation, it all depends on rest of the app
which way to go. However I don't think your use of the word
denormalise is correct. The db would not be denormalised by moving
stuff into the user table. There would be no replication of data as
it is a has_one relationship. It would not be appropriate for things
such as hobbies which would likely be a habtm relationship.

Colin

yeah... wrong term... sorry for any confusion. Encapsulation and
separation of responsibility is more the gist of why I'd keep the User
and Profile stuff apart. All personal preference and project
requirements decisions though...