Let\'s work with these classes:
class User < ActiveRecord::Base
has_many :project_participations
has_many :projects, through: :project_participations,
This is more of a rails structure thing at the level of the ruby data structures. To simplify it lets put it this way. First of all imagine User as a data structure contains:
And Project
Now when you mark a relation to be :through another (user.projects through user.project_participations)
Rails implies that when you add a record to that first relation (user.projects) it will have to create another one in the second realation (user.project_participations) that is all the effect of the 'through' hook
So in this case,
user.projects << project
#will proc the 'through'
#user.project_participations << new_entry
Keep in mind that the project.users is still not updated because its a completely different data structure and you have no reference to it.
So lets take a look what will happen with the second example
u.project_participations << pp
#this has nothing hooked to it so it operates like a normal array
So In conclusion, this acts like a one way binding on a ruby data structure level and whenever you save and refresh your objects, this will behave the way you wanted.