Can not marshal an ActiveRecord object with anything in association_cache #116

Closed
danielfarrell opened this Issue Jun 29, 2012 · 12 comments

Comments

Projects
None yet
4 participants
@danielfarrell

I thought I was running into a rails issue(rails/rails#6909) but it turns out it is an issue with this gem.

If composite_primary_keys is installed and you attempt to marshal an AR object with anything in the association_cache you receive a "singleton can't be dumped" error. It works if I clear the cache, or if I don't use a relation and instead just memoize with a find_by_user_id on the other model.

Here is a clean rails app with a couple of models with a single row in a sqlite db for each of them:
https://github.com/danielfarrell/show_marshal_error

It does not even use any composite keys. I can reproduce in the console as follows:

user = User.first
Marshal.dump(user) #works
user.location
Marshal.dump(user) #error
user.clear_association_cache
Marshal.dump(user) #works again

Any thoughts?

@cfis

This comment has been minimized.

Show comment Hide comment
@cfis

cfis Jul 2, 2012

Contributor

Hmm, do have a traceback of that error? CPK doesn't override any marshalling code, so nothing obvious jumps out at me. Its possible that CPK is overriding some other method though that is causing this to happen.

What version of Rails?

Contributor

cfis commented Jul 2, 2012

Hmm, do have a traceback of that error? CPK doesn't override any marshalling code, so nothing obvious jumps out at me. Its possible that CPK is overriding some other method though that is causing this to happen.

What version of Rails?

@danielfarrell

This comment has been minimized.

Show comment Hide comment
@danielfarrell

danielfarrell Jul 2, 2012

I'll get a traceback for you tomorrow. It happens in the latest version of Rails(3.2.6). I need to dig into the CPK code and look around still, but I'm guessing I'll find a Proc used in the association cache code, which won't marshal on MRI. More tomorrow.

I'll get a traceback for you tomorrow. It happens in the latest version of Rails(3.2.6). I need to dig into the CPK code and look around still, but I'm guessing I'll find a Proc used in the association cache code, which won't marshal on MRI. More tomorrow.

@cfis

This comment has been minimized.

Show comment Hide comment
@cfis

cfis Aug 8, 2012

Contributor

Any updates on this?

Contributor

cfis commented Aug 8, 2012

Any updates on this?

@cfis

This comment has been minimized.

Show comment Hide comment
@cfis

cfis Dec 18, 2012

Contributor

Ok, going to close. Please reopen if still an issue.

Contributor

cfis commented Dec 18, 2012

Ok, going to close. Please reopen if still an issue.

@cfis cfis closed this Dec 18, 2012

@danielfarrell

This comment has been minimized.

Show comment Hide comment
@danielfarrell

danielfarrell Dec 18, 2012

Yeah, sorry... I worked around this in our code. If I run into it again I'll bring it back up here.

Yeah, sorry... I worked around this in our code. If I run into it again I'll bring it back up here.

@tinylox

This comment has been minimized.

Show comment Hide comment
@tinylox

tinylox Apr 4, 2013

How did you work around this ? I have run into a similar issue and was wondering what the best course of action is

tinylox commented Apr 4, 2013

How did you work around this ? I have run into a similar issue and was wondering what the best course of action is

@danielfarrell

This comment has been minimized.

Show comment Hide comment
@danielfarrell

danielfarrell Apr 4, 2013

Really poorly, ha. Instead of having locations as a relation, I made it a method. For the example app given above it would be:

def location
  @location ||= Location.find location_id
end

Without the relationship it marshal's fine. :-/

Really poorly, ha. Instead of having locations as a relation, I made it a method. For the example app given above it would be:

def location
  @location ||= Location.find location_id
end

Without the relationship it marshal's fine. :-/

@tinylox

This comment has been minimized.

Show comment Hide comment
@tinylox

tinylox Apr 4, 2013

@danielfarrell perhaps this issue should be reopened ? I will do some more investigation just to confirm this is an issue with composite_primary_keys

tinylox commented Apr 4, 2013

@danielfarrell perhaps this issue should be reopened ? I will do some more investigation just to confirm this is an issue with composite_primary_keys

@danielfarrell

This comment has been minimized.

Show comment Hide comment
@danielfarrell

danielfarrell Apr 4, 2013

Yep, if you have the time to investigate it, it should be re-opened. I ran out of time and just worked around it.

Yep, if you have the time to investigate it, it should be re-opened. I ran out of time and just worked around it.

@tinylox

This comment has been minimized.

Show comment Hide comment
@tinylox

tinylox Apr 5, 2013

So I have done some more investigation it appears that this is an issue with the association. This gets stored in the association cache but even attempting

Marshal.dump(user.location)

will result in the same failure.

I think that somewhere in the code that overrides ActiveRecord's default behavior a singleton class is being introduced and the Marshall code cannot serialize it.

I do not know enough about AR or how composite primary keys alters its behavior to be able to make a clearer
assessment. I suppose I can open a new ticket if this one has fallen off the radar.

tinylox commented Apr 5, 2013

So I have done some more investigation it appears that this is an issue with the association. This gets stored in the association cache but even attempting

Marshal.dump(user.location)

will result in the same failure.

I think that somewhere in the code that overrides ActiveRecord's default behavior a singleton class is being introduced and the Marshall code cannot serialize it.

I do not know enough about AR or how composite primary keys alters its behavior to be able to make a clearer
assessment. I suppose I can open a new ticket if this one has fallen off the radar.

@danielfarrell

This comment has been minimized.

Show comment Hide comment
@danielfarrell

danielfarrell Apr 5, 2013

Yeah, I did get that far. I even got a step farther, that it was in the association cache. When you clear that cache then it will marshal.

Yeah, I did get that far. I even got a step farther, that it was in the association cache. When you clear that cache then it will marshal.

@justinweiss

This comment has been minimized.

Show comment Hide comment
@justinweiss

justinweiss Oct 3, 2013

Contributor

This is still an issue. The initialize and initialize_copy methods in https://github.com/composite-primary-keys/composite_primary_keys/blob/master/lib/composite_primary_keys/relation.rb both create singleton objects and redefine methods every time a relation is created. Once this happens, the object holding the relation cannot be marshaled. This is probably also pretty inefficient, but I haven't checked, so I don't know for sure.

This can probably be easily solved for non-cpk models by changing add_cpk_where_values_hash to an alias_method_chain, but solving it for cpk models is a little more complicated (since you probably don't want to include all of those modules at the top into every relation).

Contributor

justinweiss commented Oct 3, 2013

This is still an issue. The initialize and initialize_copy methods in https://github.com/composite-primary-keys/composite_primary_keys/blob/master/lib/composite_primary_keys/relation.rb both create singleton objects and redefine methods every time a relation is created. Once this happens, the object holding the relation cannot be marshaled. This is probably also pretty inefficient, but I haven't checked, so I don't know for sure.

This can probably be easily solved for non-cpk models by changing add_cpk_where_values_hash to an alias_method_chain, but solving it for cpk models is a little more complicated (since you probably don't want to include all of those modules at the top into every relation).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment