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

Better support for form objects #423

Open
antulik opened this issue Sep 5, 2017 · 3 comments
Open

Better support for form objects #423

antulik opened this issue Sep 5, 2017 · 3 comments

Comments

@antulik
Copy link
Contributor

antulik commented Sep 5, 2017

It's a very common use case and I'm surprised active_interaction has little to no support for it.

Almost always form objects wrap existing model or two. And all the fields need to be prepopulated from the object. This could be done with default option, but requires a lot of repetition. We've wrote an extension ourselves to automate that:

class UserForm < ActiveInteraction::Base
  object :user
  
  model_fields :user do
    string :name
    string :email
  end
  
  def execute 
    user.update changed_model_fields(:user)
    errors.merge!(user.errors)
  end
end

user = User.create(name: 'Tom', email: '[email protected]')

UserForm.new(user).name #=> 'Tom'
UserForm.run(user: user, name: 'Sam') 
user.name #=> 'Sam'

model_fields is a new method which marks fields to be defaulted from model. Fields nested under model_fields are populated from the model if no value is given.

changed_model_fields method returns the fields which assigned to the model in model_fields and have changed

It works well for us, so would like the see native support of the similar feature in the gem.
Thoughts?

@AaronLasseigne
Copy link
Owner

This has given me some interesting ideas. I've been wanting to improve this for a bit. I think I can integrate it with some other new 4.0.0 features.

@aganov
Copy link

aganov commented Feb 2, 2018

Also reform gem supports a feature called collection. It can be used with rails's fields_for helper. It will be great if we have something similar here...

# Example form object (pseudo code)
class ProfileForm < ActiveInteraction::Base
  object :model
  string :name

  collection :pages do
    integer :id
    string :provider
    string :url
  end

  def execute
    # sync properties with model properties
    model.save
  end
end
# controller
@form = ProfileForm.new(Profile.new)
# view
= simple_form_for @form do |f|
  = f.input :name
  = f.simple_fields_for :pages do |pf|
    = pf.input :id, as: :hidden
    = pf.input :url
  = f.button :submit

@h0jeZvgoxFepBQ2C
Copy link

h0jeZvgoxFepBQ2C commented Nov 20, 2023

any solution found for this in the meantime? I tried many things, but nothing worked out?

We would like to use it with arrays of classes?

class TestInteraction < ActiveInteraction::Base
  
  array :users, index_errors: true do
    User
  end
  def execute
    users
  end
end


=form_for (@dd = TestInteraction.new(users: User.limit(3) + [User.new]) do |f|
   =# f.fields_for :users do |ff| also didnt work
   =f.fields_for "users[]", @dd.users do |ff|
    =ff.text_field :firstname
    =ff.text_field :lastname

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

No branches or pull requests

4 participants