Skip to content
This repository has been archived by the owner on Dec 12, 2021. It is now read-only.

Wrong names/IDs for some doubly nested forms #49

Closed
eostrom opened this issue May 30, 2011 · 3 comments
Closed

Wrong names/IDs for some doubly nested forms #49

eostrom opened this issue May 30, 2011 · 3 comments
Labels

Comments

@eostrom
Copy link

eostrom commented May 30, 2011

Here's a skeletal example. Model relations:

User has_many :projects
Project has_many :tasks

Simple form:

= nested_form_for(@user) do |f|
  .projects
    = f.fields_for :projects do |pf|
      .tasks
        = pf.fields_for :tasks do |tf|
          = tf.text_field :description
          = tf.link_to_remove 'Remove this task'
        = pf.link_to_add 'Add a task', :tasks
      = pf.link_to_remove 'Remove this project'
    = f.link_to_add 'Add a project', :projects
  = f.submit

If you click 'Add a project' and then 'Add a task', you'll get an input with a name like user[projects_attributes][new_1306716504432][tasks_attributes][new_1306716506218][description]. If you click 'Add a task' again, you'll get another input with exactly the same name.

The IDs won't be exact duplicates. The first and second IDs in this test run were:

user_projects_attributes_new_1306716504432_projects_tasks_attributes_new_1306716506218_description
user_projects_attributes_new_1306716504432_projects_tasks_attributes_new_1306716506218_tasks_description

I think the problem is this line in nested_form.js:

var context = ($(this).closest('.fields').find('input:first').attr('name') || '').replace(new RegExp('\[[a-z]+\]$'), '');

If I had a text field for the project name before the nested tasks, then input:first would be the project name, and the context would be the project. But I don't, and so input:first is the hidden "destroy project" input. But the second time I add a task, input:first is the description field for the first project.

It may also be that this line is fine, and the subsequent code is trying to be smart about handling a context that could be either "the surrounding object" or "an existing sibling of the new object", but getting it wrong. I haven't dug into that code yet.

If I change the selector from input:first to input:last, it works for me, because it always picks up the "destroy project" input. But if the "Remove this project" link were above the tasks instead of below it, it would break the same way it's breaking for me now.

I guess another workaround is just to put the remove link above the associations. But unfortunately in my real use case, there is no remove link, and the context seizes on some other input. I suspect there's just an inherent brittleness to this method of using existing inputs to figure out context.

I'm using the master branch at 89953fa.

@ryanb
Copy link
Owner

ryanb commented May 30, 2011

Thanks for the detailed error report, I'll look into fixing this when I get a chance. If anyone else wants to take a crack at it feel free to submit a pull request.

@lest
Copy link
Collaborator

lest commented Jun 8, 2012

@eostrom Could you please test with the latest version?

lest added a commit to lest/nested_form that referenced this issue Aug 21, 2012
@lest
Copy link
Collaborator

lest commented Aug 21, 2012

I added test in 332a2e0 and merged #186 to fix it.

@lest lest closed this as completed Aug 21, 2012
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants