activegraph icon indicating copy to clipboard operation
activegraph copied to clipboard

Cannot update properties of ActiveNode models with custom writers

Open mvuk opened this issue 5 years ago • 1 comments

I find that I am unable to update a property from an ActiveMode model when I include a custom writer. Take this for a reduced example from my models:

class Person

  property :first_name, type: String

  def first_name=(first_name)
    super(first_name.to_s.gsub(/[\b\v\s+]/, '').capitalize.match(NAME_REGEX))
  end

end

When I create a new object from scratch with lowercase full name, it always works fine. The lower case name formats to uppercase, validates, and is stored properly.

When I go to update the object, the updated object will not save. I have tried everything from test models, the rails controller, irb/rails c. Immediately I get a response that the attribute is updated, but when I query the database I notice that it is not updated.

Let's say we have that in a @vendor instance variable. At any stage of the vendors#update controller method when I run puts @vendor.first_name, it will return the new first_name. However, it does not actually save.

I can even run:

@vendor.update_attributes(first_name: "Ralph")
@vendor.save
@vendor.first_name # returns "Ralph"

Then when I query the database... the model still has the previous name. Not "Ralph"!

My hunch here is that when I overwrite :property first_name with a my own method, something is being overwritten that was included with Neo4j.rb in ActiveNode.

So then how is possible to work with custom writers to set up and validate my properties in Neo4j?

mvuk avatar Sep 10 '18 00:09 mvuk

Ah, so I'm guessing that the problem is that the call to property is defining the writer in the Person model itself, not in the super class. I'm not sure what your call to super is doing, as my assumption would be that there is no super first_name method for your class.

Off hand, I'd try aliasing the original method to something else so that it isn't overwritten, allowing you to call it in the new method. I.e.

class Person

  property :first_name, type: String

  alias_method :original_first_name=, :first_name=

  def first_name=(first_name)
    original_first_name = first_name.to_s.gsub(/[\b\v\s+]/, '').capitalize.match(NAME_REGEX)
  end

end

I've never actually tried using an alias with a setter, so I'm not sure if there's anything special to it.

Assuming this works, I don't think this is a Neo4jrb issue, but rather just the way Ruby works.

jorroll avatar Sep 11 '18 06:09 jorroll