Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

add _delete key for accepts_nested_attributes_for ?

#4655

There is a _destroy key for nested model now, which indicates to destroy the associated object when set to true. It would be great if rails can also add a _delete key, which will delete the object when set to true. (The difference between destroy and delete, according to rails documentation: associated_collection#destroy will destroy the endpoint, while associated_collection#delete will destroy the join model only.)

e.g.

class Post
  has_many :post_tags
  has_many :tags, :through => :post_tags
  accept_nested_attributes_for :tags, :allow_destroy => true
end

In this case, most people want to unlink post with tags only, instead of destroying tags (I guess).

Reported by Jan Xie · May 20th, 2010 @ 04:19 AM

State: stale
Milestone: none
Assigned to: nobody
Importance: none

Activity

  1. Damien MATHIEU
    Damien MATHIEU

    I wouldn't be sure there's the need for two different attributes. The behavior of the nested model depends of the relation configuration.
    Here, you don't want the tag to be deleted when it's relation with the post is.

    Then you set your relation with a :dependent option to delete.

    has_many :tags, :through => :post_tags, :dependent => :delete
    

    I guess every time you want to delete a nested relation, you want to do it the same way.
    Or at least if at some point, you want to delete the tag, it's not an interface implementation but a logic one. So it should remain in the activerecord's relation.

    May 20th, 2010 @ 08:25 AM

  2. Jan Xie
    Jan Xie

    I tried this way (and many other ways) of using :dependent, I think it doesn't work (I'm using rails on github). And in rails code it says:

    #   *Warning:* This option is ignored when used with <tt>:through</tt> option.
    

    ref: http://github.com/rails/rails/blob/master/activerecord/lib/active_r...

    If this does work, then yes my proposal is needless.

    May 20th, 2010 @ 10:43 AM

  3. Rizwan Reza
    Rizwan Reza
    • No changes were found…

    May 21st, 2010 @ 12:43 AM

  4. Santiago Pastorino
    Santiago Pastorino
    • State changed from new to open

    This issue has been automatically marked as stale because it has not been commented on for at least three months.

    The resources of the Rails core team are limited, and so we are asking for your help. If you can still reproduce this error on the 3-0-stable branch or on master, please reply with all of the information you have about it and add "[state:open]" to your comment. This will reopen the ticket for review. Likewise, if you feel that this is a very important feature for Rails to include, please reply with your explanation so we can consider it.

    Thank you for all your contributions, and we hope you will understand this step to focus our efforts where they are most helpful.

    February 9th, 2011 @ 12:31 AM

  5. Santiago Pastorino
    Santiago Pastorino
    • State changed from open to stale

    February 9th, 2011 @ 12:31 AM

  6. bingbing
  7. alberto
    alberto

    This request seems to have sense to me, since I agree with you there is no simple way (i.e. without using before_save hooks) to just delete the relationship without destroying the object. I would like to have the ticket re-opened or to see some more explanation.

    April 5th, 2011 @ 07:32 PM

  8. alberto
    alberto

    P.S. the same is true if you have an HABTM relation instead of an has_many :through.

    April 5th, 2011 @ 07:34 PM

  9. Kane
    Kane

    alberto

    This request seems to have sense to me, since I agree with you there is no simple way

    This request does not make any sense to me.
    it does what it says, it destroys the tag.

    the so call "no simple way"

     some_post.tags.clear
    

    you may want to simply stick to associations instead of nested attributes for your use case.
    or simply use has_and_belongs_to_many if your join model needs no logic.

    Jan Xie

    In this case, most people want to unlink post with tags only, instead of destroying tags (I guess).

    if you want this you may simply want to use the shown method.
    Also you probably want to define dependent destroy for the join model, so you dont leave orphans behind if you destroy a tag or a post.

    class Post
      has_many :post_tags, :dependent => :destroy
    end
    
    class Tag
      has_many :post_tags, :dependent => :destroy
    end
    

    please set this to invalid.

    April 6th, 2011 @ 12:30 AM

  10. alberto
    alberto

    I agree with almost everything. The only arguable thing is:

    you may want to simply stick to associations instead of nested attributes for your use case.

    If this is the philosophy behind nested attributes (i.e. «you simply CAN'T do this with nested attributes, manage the associations by your self, you moron!») than it's ok. But I don't see any reason why one shouldn't want this non-destructive behavior while still using nested attributes.

    Btw, my "no simple way" referred to the fact that standard forms (e.g. nested_form_for) rely on the product.tags_attributes array. If you want to use them (and they're great to keep your views clean) and NOT destroy associated objects, you have to do something like

    before_safe god_save_the_tags!
    private
      def god_save_the_tags!
        tags.select(&:marked_for_detruction?).each do |tag|
          tag.reload # Notice that there is no "unmark_for_destruction" right now,
                     # but I'm pretty sure I saw a related ticket somewhere here
          tags.delete(tag)
        end
      end
    

    April 6th, 2011 @ 12:44 AM

  11. Kane
    Kane

    I see.

    It would be nive if :destroy and :delete would behave exactly as calling the corresponding methods on the association.

    April 6th, 2011 @ 04:26 PM