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

Allow to use with Arrays and non-associations #90

Merged
merged 6 commits into from
Sep 24, 2012
Merged

Allow to use with Arrays and non-associations #90

merged 6 commits into from
Sep 24, 2012

Conversation

dnagir
Copy link
Contributor

@dnagir dnagir commented Sep 24, 2012

This PR allows to use cocoon with custom methods and doesn't bind it to AR only.
So ActiveAttr or just transient methods can be used.

  • Fix the issue when error is raised when an association doesn't exist (Cocoon for Array fields #85).
  • Allow to build the form for Non-AR associations, plural and singular. The only requirement is a method build_<association>.
  • Raise a descriptive error when it isn't association and no build_<association> method is defined.
  • Minor refactoring of create_object

May deal with the related issues: #79, #85, #86

@nathanvda
Copy link
Owner

This seems like great work. I will have an in depth look at it tonight. Indeed, if I understand correctly, this could handle the array-fields as well, if somebody would add the correct method build_<array-field>.

@dnagir
Copy link
Contributor Author

dnagir commented Sep 24, 2012

Yes, exactly.
Ideally I wold like to pass the builder method via options too.
But the convention in this PR should be a good start and sufficient for 95% of cases.

If you'll accept it, we would have to add it to README too I suppose.

On 24/09/2012, at 21:37, Nathan Van der Auwera notifications@github.com wrote:

This seems like great work. I will have an in depth look at it tonight. Indeed, if I understand correctly, this could handle the array-fields as well, if somebody would add the correct method build_.


Reply to this email directly or view it on GitHub.

nathanvda added a commit that referenced this pull request Sep 24, 2012
Allow to use with Arrays and non-associations
@nathanvda nathanvda merged commit 64fd7e7 into nathanvda:master Sep 24, 2012
@dnagir
Copy link
Contributor Author

dnagir commented Sep 25, 2012

@nathanvda thanks for merging it in. I wonder when are you planning to release it?

@nathanvda
Copy link
Owner

I want to update my demo-project and then I will release it. I hope to finish that on wednesday.

This was referenced Oct 8, 2012
@gdlx
Copy link
Contributor

gdlx commented Dec 4, 2012

I tried this way to handle array fields and it works with "link_to_add_association".

I'm just not sure of what should be in "build_[array field]" method and what's the difference between "build_[singular array field]" and "build_[plural array field]" as noted into specs.

I've tried this and it seems to work but it doesn't seem very clean to me :

    def build_paths
      { :"" => "" }
    end

I get an error if I provide an array since the field name method doesn't exsits.

A small example would be nice ;-)

Note that, for array fields, the field has to be set like this in the partial : f.input "" (simple_form) since we need empty brackets in html input name (name="object[paths][]" ; There should be indexes but it doesn't work...)

The big issue is that link_to_remove_association doesn't work at all because of is_dynamic = f.object.new_record? in line 27. As there's no model (f.objectis nil), there's no new_record?method.

For now, I juste don't use link_to_remove_association and reject empty array entries.

@gdlx
Copy link
Contributor

gdlx commented Dec 4, 2012

There's another problem : I don't know how to recover existing array values in the form.

Changing build_paths to this raises an error :

    def build_paths
      paths
    end

Actually, the purposed design doesn't really fit with array fields since you're waiting for a 'virtual' association and field names. But an array has a single field with no name.

My initial (not very clean) pull request was made to specifically handle this case. I don't see how to do it with this new feature. It's made for non AR compatible models but a model with fields is still required...

@nathanvda
Copy link
Owner

I will try to add an example later this evening or tomorrow morning.

@dnagir
Copy link
Contributor Author

dnagir commented Dec 5, 2012

@porecreat here's an example (stripped down a bit). All you need is the build_additional_participation (which in your case could be build_paths or build_path returning a new ActiveModel model instance):

class CompanyInvitation < ActiveRecord::Base
  attr_accessor :additional_participations

  def additional_participations
    @additional_participations ||= parse_additional_participations
  end

  def build_additional_participation
    Participation.new # Required by cocoon for the nested forms - return a single instance of a new object
  end

  def additional_participations_attributes=(values)
    @additional_participations = values.each.map do |k, params|
      params.delete('_destroy')
      # Convert user_email, user_fn etc into {user => email, fn etc}
      user_params = Hash[ Participation::USER_FIELDS.map{|f| [f, params["user_#{f}"]]} ]
      user_params['password_confirmation'] = user_params['initial_password'] = user_params['password']
      Participation.new(params.merge('user_attributes' => user_params)).tap do |p|
        p.company = company
      end
    end
  end
end

@jlgasparrini
Copy link

I know this is a little old but... thank you @dnagir! You save my life 👍

@mingca
Copy link

mingca commented Jul 17, 2018

Can we have the same feature for link_to_remove_association?

timdavies pushed a commit to tusker-direct/cocoon that referenced this pull request Apr 1, 2019
This complements already accepted PR
nathanvda#90

That PR allowed using cocoon on ActiveRecord models
with nested Array items.
But still the main form object had to be ActiveRecord.

This commit removes that restriction and allows
using cocoon with plain ActiveModel-compliant objects
(including the object for the main form).

This has been requested in the issue below but went unnoticed
nathanvda#141

Usage example (model only side)

```ruby

class User
  include ActiveAttr::Model
  attribute :email
end

class Company
  include ActiveAttr::Model

  def users
    @users ||= []
  end

  # This will allow setting the attributes from `fields_for` rails helper
  # when the form will be posted
  def users_attributes=(attrs)
    # update the users array...
  end

  # cocoon uses this method to render the template
  def build_user
    User.new # blank state for new template
  end
end

```
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

Successfully merging this pull request may close these issues.

5 participants