0

I have a single table inheritance mechanism and a controller method that creates objects based on a text type.

From my controller:

tile = Object.const_get(tile_data[:type]).new(params_from_tile(tile_data))

tile.save

inside my model base class I have several before create hooks:

before_create :set_handle, :upload

It appears none of my hooks are firing, does it have something to do with my use of Object.const_get to create my objects?

Edit: I've managed to work around this by not using Object.const_get().new now I'm just invoking my Tile.new directly, and there does not appear to be any negative repercussions, so yeah.

acolchagoff
  • 1,926
  • 3
  • 18
  • 30
  • Your code is not *creating* records but only *initializing* it, therefore your `before_create` callbacks are not executed. Use `.create(...)` instead of `.new()` OR use `after_initialize` callback – MrYoshiji Aug 02 '17 at 17:54
  • Sorry, I omitted that part, I am calling .save – acolchagoff Aug 02 '17 at 17:55
  • Try raising an error in either `set_handle` or `upload` and see if that error is raised or not. This way you will be sure if these callbacks are triggered or not. – MrYoshiji Aug 02 '17 at 17:59
  • I think I've answered my own question, not using Object.const_get().new fixed the issue. – acolchagoff Aug 02 '17 at 19:33

2 Answers2

1

Theoretically, there is no difference how you access the class, both of these would behave exactly same:

Tile.new(params_from_tile(tile_data))

and

Object.const_get("Tile").new(params_from_tile(tile_data))

Your seeing bad behaviour may have to do with some other small thing missing.

May be tile_data[:type] in your example pointing to something else, did you make sure Tile record gets saved without callback. Can you try with Object.const_get("Tile") and see what happens.

Vijay Agrawal
  • 1,643
  • 12
  • 17
0

I've changed this to invoke the baseclass directly:

Tile.new(params_from_tile(tile_data))

And now my hooks are being called as expected, so I'm not sure why this behaves this way, and would appreciate a better answer from someone who knows, but it appears that the answer is that using Object.const_get().new to create an object skips all hooks. On a side note, Invoking create on the baseclass with just a type attribute will still cause subclass hooks to fire, So thats nice.

acolchagoff
  • 1,926
  • 3
  • 18
  • 30
  • That's weird. A const is a const. Shouldn't matter how you get it. If you could prepare an example rails app that demonstrates the problem, I'd tell you why it happens :) – Sergio Tulentsev Aug 02 '17 at 19:40