0

I got the example from this blog: https://robertheaton.com/2015/08/31/migrating-bajillions-of-database-records-at-stripe/ Basically trying to proxy a save to project.description to a my_proxy table.

class Project < ApplicationRecord
   def self.my_proxy(model_prop_name, my_prop_name)
    model_prop_name_set = :"#{model_prop_name}="
    original_model_prop_name_set = :"original_#{model_prop_name_set}"

    # Question: In the blog, it used method_defined? which returned false, I updated it to attribute_method?
    # bug then now, alias_method fails to recognize model_prop_name_set (can't find it on the 
    # class) although it should be an instance method.
    # I basically want to alias this ActiveRecord instance method, inside the self.my_proxy
    # class method
    alias_method original_model_prop_name_set, model_prop_name_set if attribute_method?(model_prop_name_set)

    define_method(model_prop_name_set) do |val|
      public_send(original_model_prop_name_set, val)

      my_proxy.public_send(:"#{signoff_prop_name}=", val)
    end
  end 

  myf_proxy :description, :description
end

Project has a description field, so it has a description= attribute setter. I want to send that to a proxy record. This example is probably outdated, the method_defined? part in the blog example returned false, so I had to change to attribute_method? The alias_method part next choking up

NameError (undefined method `description=' for class `#<Class:0x00007fddc0689318>')

Also found this post alias_method on ActiveRecord::Base results in NameError, to say use alias_attribute, but throwing that in there would result in a stack too deep error.

frank
  • 1,283
  • 1
  • 19
  • 39
  • `method_defined` should work. If it returns false, it means it's not defined. Sure you passed in the correct `model_prop_name`? – EJAg Mar 17 '20 at 23:09
  • Yeah, I am pretty sure I passed in the right thing or else attribute_method? wouldn't returned true. – frank Mar 18 '20 at 00:26

1 Answers1

0

Instead of doing an alias_method, I found a way to accomplish what I needed to do by defining the setter method (ie. :description=) with define_method, and inside there, invoke write_attribute(:description=, val), and everything worked as expectted.

class Project < ApplicationRecord
   def self.my_proxy(model_prop_name, my_prop_name)
    model_prop_name_set = :"#{model_prop_name}="

    define_method(model_prop_name_set) do |val|
      write_attribute(model_prop_name, val)

      my_proxy.public_send(:"#{signoff_prop_name}=", val)
    end
  end 

  myf_proxy :description, :description
end
frank
  • 1,283
  • 1
  • 19
  • 39