Rails: How can I access the parent model of a new

2019-04-28 05:44发布

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.)

2条回答
你好瞎i
2楼-- · 2019-04-28 06:39

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.

查看更多
祖国的老花朵
3楼-- · 2019-04-28 06:45

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.

查看更多
登录 后发表回答