Sai
Sai

Reputation: 7209

Rails: How can I access the parent model of a new record's nested associations?

Suppose we have the standard Post & Comment models, with Post having accepts_nested_attributes_for :commments and :autosave => true set.

We can create a new post together with some new comments, e.g.:

@post = Post.new :subject => 'foo'
@post.comments.build :text => 'bar'
@post.comments.first # returns the new comment 'bar'
@post.comments.first.post # returns nil :(
@post.save # saves both post and comments simultaneously, in a transaction etc
@post.comments.first # returns the comment 'bar'
@post.comments.first.post # returns the post 'foo'

However, I need to be able to distinguish from within Comment (e.g. from its before_save or validation functions) between

  1. this comment is not attached to a post (which is invalid)
  2. this comment is attached to an unsaved post (which is valid)

Unfortunately, merely calling self.post from Comment doesn't work, because per above, it returns nil until after save happens. In a callback of course, I don't (and shouldn't) have access to @post, only to self of the comment in question.

So: how can I access the parent model of a new record's nested associations, from the perspective of that nested association model?

(FWIW, the actual sample I'm using this with allows people to create a naked "comment" and will then automatically create a "post" to contain it if there isn't one already. I've simplified this example so it's not specific to my code in irrelevant ways.)

Upvotes: 6

Views: 2852

Answers (2)

Luke Francl
Luke Francl

Reputation: 31444

I think it is strange that Rails does not let you do this. It also affects validations in the child model.

There's a ticket with much discussion and no resolution in the Rails bug tracker about this:

Nested attributes validations circular dependency

And a proposed resolution:

nested models: build should directly assign the parent

Basically, the deal is, the nested attributes code doesn't set the parent association in the child record.

There's some work-arounds mentioned in the second ticket I linked to.

Upvotes: 6

MattMcKnight
MattMcKnight

Reputation: 8290

I don't think you can do this. On the other hand, your validations shouldn't be failing, as the order of the transaction will create the post record before saving the comment.

Upvotes: 0

Related Questions