Forum: Ruby on Rails Rails 4 deprecation of in-place edit methods for collection associations

2b04479fb847d7177977ac759769ce34?d=identicon&s=25 George Georgiev (georgiev)
on 2013-09-17 08:11
(Received via mailing list)
Hi everyone!

For those of you who are not noticed the in-place edit method for
collection associations are broken in the current rails release - 4.0.0,
and here's what is cooking in the rails master
https://github.com/rails/rails/commit/1a40be021132...
and this https://github.com/rails/rails/pull/12227

In short: it looks like things like has_many.reject!{},
has_many.select!{},
has_many.delete_if{}, has_many.pop etc. will not work as of Rails 4.2.
I tried to get some answers about the motivation of this decision here
https://github.com/rails/rails/pull/12236 but i failed.

So to the question can someone please explain WHY is this happening?
Where is the "confusion" in the examples above?

PS.
I have read the CHANGELOG - it does not explain the motivation.
And please, I don't thing that "This behavior was changed by design. We
choose to not support this in Rails 4.0 and we will not bring it back"
and "The
decision was already made and like I said we will not change it back
since
it introduce more confusion than feature" are answers to my question at
all.
2b04479fb847d7177977ac759769ce34?d=identicon&s=25 George Georgiev (georgiev)
on 2013-09-21 08:20
(Received via mailing list)
Monkey patch gem to revert to per rails 4 behaviour
http://rubygems.org/gems/rails4-editable-collections
6883e5ef03484d4fcef507d7b4f1d243?d=identicon&s=25 Matt Jones (Guest)
on 2013-09-23 16:00
(Received via mailing list)
On Tuesday, 17 September 2013 00:43:15 UTC-5, George Georgiev wrote:
> has_many.select!{}, has_many.delete_if{}, has_many.pop etc. will not work
> as of Rails 4.2.
> I tried to get some answers about the motivation of this decision here
> https://github.com/rails/rails/pull/12236 but i failed.
>
> So to the question can someone please explain WHY is this happening?
> Where is the "confusion" in the examples above?
>

 Another related ticket: https://github.com/rails/rails/issues/12140

The problem is that using (for instance) delete_if on a collection
removes
things from the in-memory version but doesn't persist the changes. It
*can't* persist the changes, since the records have been removed from
the
association's list of records. This is EXACTLY the "confusion"
referenced
in the tickets.

One of your examples in 12236 highlights this issue: these two code
snippets (in Rails 3 or 4) do not do the same thing:

post.comments.select! { |comment| comment.not_spam? }
# => filters the array in-memory but does not unlink objects

vs

comments = post.comments.to_a
comments.select! { |comment| comment.not_spam? }
post.comments = comments
# => unlinks comments that aren't in the filtered array

--Matt Jones
5b50fec1e5bf39bb4d75b199130882f7?d=identicon&s=25 Josh Jordan (Guest)
on 2013-09-24 14:20
(Received via mailing list)
The justification for this change seems preposterous. Why would anyone
think that, in the former example, the database has changed? The method
called there is named "select!".

This sounds like a case of a few people writing fragile code without any
understanding of what they were doing or the systems they work on, and
complaining about it. I suggested that a simple bit of documentation
would
solve the problem. It doesn't seem to make much sense to make this
particular interface so inconsistent with the rest of ActiveRecord,
which
absolutely allows you to modify objects in memory.
2b04479fb847d7177977ac759769ce34?d=identicon&s=25 George Georgiev (georgiev)
on 2013-09-25 07:50
(Received via mailing list)
Thank you Matt!!
Now I see my own confusion - I was convinced that these two snippets are
identical in Rails 3 (Well, they are - JUST in MY case)

When they do the same thing - when the collection contains only new
records
(hence no unlinking required).
In all other cases in-place filtering doesn't work even in Rails 3 as
you
pointed out.

But I still disagree that dropping the in-place methods (and breaking
the
Collection contract) is the best solution.

Thank you once again for clarifying!!
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.