Has_many through association on unsaved objects

Hello,

I just stumbled upon a behaviour about associations I do not really
understand why Rails/ActiveRecord cannot get the connection. Using
activerecord (4.2.0.beta2).

To describe it, lets work with theses models:

class User < ActiveRecord::Base
has_many :project_participations
has_many :projects, through: :project_participations, inverse_of:
:users
end

class ProjectParticipation < ActiveRecord::Base
belongs_to :user
belongs_to :project

enum role: { member: 0, manager: 1 }

end

class Project < ActiveRecord::Base
has_many :project_participations
has_many :users, through: :project_participations, inverse_of:
:projects
end

A user can participate in many projects with a role as a member or a
manager. The connecting model is called ProjectParticipation.

I now have a problem using the associations on unsaved objects. The
following commands work like I think they should work:

first example

u = User.new
p = Project.new

u.projects << p

u.projects
=> #<ActiveRecord::Associations::CollectionProxy [#]>

u.project_participations
=> #<ActiveRecord::Associations::CollectionProxy [#<ProjectParticipation
id: nil, user_id: nil, project_id: nil, role: nil>]>

So far so good - AR created the ProjectParticipation by itself and I can
access the projects of a user with u.projects.

But it does not work if I create the ProjectParticipation by myself:

second example

u = User.new
pp = ProjectParticipation.new
p = Project.new

pp.project = p # assign project to project_participation

u.project_participations << pp # assign project_participation to user

u.project_participations
=> #<ActiveRecord::Associations::CollectionProxy [#<ProjectParticipation
id: nil, user_id: nil, project_id: nil, role: nil>]>

u.projects
=> #<ActiveRecord::Associations::CollectionProxy []>

Why are the projects empty? I cannot access the projects by u.projects
like
before, even the ProjectParticipation is there.

But if I go through the participations directly, the project shows up:

u.project_participations.map(&:project)
=> [#]

Shouldn’t it work like the first example directly:
u.projects returning me all projects not depending on whether I create
the join object by myself or not? Or how can I make AR aware of this?

On Thursday, 30 October 2014 13:56:51 UTC-4, Markus D. wrote:

has_many :project_participations

class Project < ActiveRecord::Base

u.project_participations
u = User.new
u.projects

Shouldn’t it work like the first example directly:
u.projects returning me all projects not depending on whether I create the join
object by myself or not? Or how can I make AR aware of this?

u.projects is going to load things from the database if the record is
saved, but otherwise it will only return objects you’ve explicitly
stored
in it.

The through association is not the same as just mapping &:project
over
project_participations.

Can you describe what you’re trying to do in more detail? There’s likely
a
way to make AR do the right thing.

–Matt J.