Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reform assigns nested properties in twins in a wrong way #402

Open
tilod opened this issue Sep 21, 2016 · 0 comments
Open

Reform assigns nested properties in twins in a wrong way #402

tilod opened this issue Sep 21, 2016 · 0 comments

Comments

@tilod
Copy link

tilod commented Sep 21, 2016

Reform version: 2.2.1

Given: I have a very complex data structure which I compose into a Twin with nested properties. The Twin then serves as model for a Form:

require 'disposable'
require 'reform'
require 'rails'
require 'reform/rails'
require 'reform/form/active_model/validations'
Reform::Form.class_eval do
  include Reform::Form::ActiveModel::Validations
end

User    = Struct.new(:email, :password, :profile) { def save; end }
Profile = Struct.new(:name) { def save; end }

class ProjectTwin < Disposable::Twin
  feature Save
  feature Sync

  property :email
  property :password
  property :profile do
    property :name
  end
end

class ProjectForm < Reform::Form
  property :email
  property :password
  property :profile do
    property :name
  end
end

user   = User.new('test@example.com', '123456', Profile.new('Test Name'))
twin   = ProjectTwin.new(user)
form   = ProjectForm.new(twin)
params = { email: 'new@example.com', profile: { name: 'New Name' } }

form.validate(params)

What I expect: On form.save (or form.sync and then twin.sync), the form writes the values from the params hash to the twin and the twin then writes the values to the nested objects without reassigning the nested properties.

What actually happens: Reform assigns the nested Twin (i.e. an instance of the anonymous class it generates to wrap the nested model) to the model:

# before save:
user.profile.class
# => Profile   ... and should stay that way

# now we save:
form.save

# what happened to the nested object?
user.profile.class
# => #<Class:0x007fb403211358>

# ...which is the anonymous class generated by the twin to wrap the nested profile model:
twin.profile.class
# => #<Class:0x007fb403211358>

Additional info: If you don't use a form but assign the values to the twin manually, twin.sync will work as expected:

user = User.new('test@example.com', '123456', Profile.new('Test Name'))
twin = ProjectTwin.new(user)
twin.email = 'new@example.com'
twin.profile.name = 'New Name'
twin.sync
user.profile.class
# => Profile

So the problematic behavior is in Reform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant