Hi guys,
Thanks in advance for this great project, really good job. I was looking for something like that such a long time.
I was digging around and I have missed and option to build nested forms. I don麓t know if there is an easy way to do it. IMHO its needed for the example app when you add line items to an order. Its painful to first create an order, save it then create line items and associate it. This happens on all kind of database models and It would be amazing to have this feature.
I think you can achieve this behaviour by adding custom fields types, overriding form view. Although you must allow nested attributes on your models.
Let me know what do you think about it and set a guidelines to approach this feature.
Thanks in advance and keep pushing!
hey, @ismaGNU - thanks! Glad to hear you like it!
You're right - at the moment we don't support nested forms. There are a couple ways you could implement it yourself, though.
If we're sticking with the Order/LineItem example from the demo app, you could create a NestedLineItemField that took care of the nested form logic. That would look something like this:
rails generate adminsitrate:field NestedLineItem
This would create:
app/fields/nested_line_item_field.rb
app/views/fields/nested_line_item_field/_show.html.erb
app/views/fields/nested_line_item_field/_index.html.erb
app/views/fields/nested_line_item_field/_form.html.erb
You can inherit from Administrate::Field::HasMany as a starting point for the behavior. This might be a good direction to start in:
diff --git a/spec/example_app/app/fields/nested_line_item_field.rb b/spec/example_app/app/fields/nested_line_item_field.rb
index e69de29..73e2d7d 100644
--- a/spec/example_app/app/fields/nested_line_item_field.rb
+++ b/spec/example_app/app/fields/nested_line_item_field.rb
@@ -0,0 +1,4 @@
+require "administrate/fields/base"
+
+class NestedLineItemField < Administrate::Field::HasMany
+end
diff --git a/spec/example_app/app/views/fields/nested_line_item_field/_form.html.erb b/spec/example_app/app/views/fields/nested_line_item_field/_form.html.erb
index e69de29..78ae901 100644
--- a/spec/example_app/app/views/fields/nested_line_item_field/_form.html.erb
+++ b/spec/example_app/app/views/fields/nested_line_item_field/_form.html.erb
@@ -0,0 +1,7 @@
+<%= f.label field.attribute_key %>
+
+<%= f.fields_for field.attribute_key do |nested_form| %>
+ <fieldset>
+ <%= nested_form.text_field :nested_attribute %>
+ </fieldset>
+<% end %>
diff --git a/spec/example_app/app/views/fields/nested_line_item_field/_index.html.erb b/spec/example_app/app/views/fields/nested_line_item_field/_index.html.erb
index e69de29..758e0c5 100644
--- a/spec/example_app/app/views/fields/nested_line_item_field/_index.html.erb
+++ b/spec/example_app/app/views/fields/nested_line_item_field/_index.html.erb
@@ -0,0 +1 @@
+<%= pluralize(field.data.count, field.attribute.to_s.humanize.downcase) %>
diff --git a/spec/example_app/app/views/fields/nested_line_item_field/_show.html.erb b/spec/example_app/app/views/fields/nested_line_item_field/_show.html.erb
index e69de29..1166a16 100644
--- a/spec/example_app/app/views/fields/nested_line_item_field/_show.html.erb
+++ b/spec/example_app/app/views/fields/nested_line_item_field/_show.html.erb
@@ -0,0 +1,20 @@
+<% if field.resources.any? %>
+ <%= render(
+ "collection",
+ collection_presenter: field.associated_collection,
+ resources: field.resources
+ ) %>
+
+ <% if field.more_than_limit? %>
+ <span>
+ <%= t(
+ 'administrate.fields.has_many.more',
+ count: field.limit,
+ total_count: field.data.count,
+ ) %>
+ </span>
+ <% end %>
+
+<% else %>
+ <%= t("administrate.fields.has_many.none") %>
+<% end %>
And here are some places in the codebase you might want to use for reference:
Right now we're focusing on stability, so it might be a while before we get to this. If you can get it working well for your project, let us know how you did it - that's probably the best way to push this forward.
Let me know if you have any questions, or if I can help out at all!
Thanks @graysonwright, that was my first approach, building LineItemField and inherits from HasMany one. The problem is that I want to have a button to add as line items as I want. So I am stuck at this part.
Anyway, I really appreciate your help and I麓ll let you know my progress :dancer:
@ismaGNU Do you have some sample code on Github for your implementation of nested form fields?
@5minpause no man, I am not be able to make it works like I expected. Do you have any ideas? I just make what I told before, but It doesn麓t work.
Not sure if this is exactly what the OP had in mind, but I've been able to incorporate Cocoon into Administrate, but with some hacks. I'll swing back around and work on a way to create a PR (or several) out of this work, because I think this is pretty important to have.
@mcmire - any updates?
@graysonwright Not yet unfortunately, I haven't had much time lately.
So I have been able to incorporate Cocoon... almost, but it is getting stuck saying that the attributes are not permitted. How do I allow the attributes, when they are already in the controller?
app/fields/nested_answer_field.rb
require "administrate/field/has_many"
class NestedAnswerField < Administrate::Field::HasMany
def to_s
data
end
end
app/controllers/questions_controller.rb (verified this works in normal rails scaffold edit)
def question_params
params.require(:question).permit( :question, :note, :kind, :has_sub, :parent_id, :answer_ids, answers_attributes: [:id, :answer, :question_id, :_destroy])
end
Here is a screen shot showing it working after adding from normal edit page. All the js works, but get this in my log "Unpermitted parameter: answers_attributes", which are clearly allowed

@airjoshb I've added nested params by overriding the resource_params method https://github.com/thoughtbot/administrate/blob/2aca8bbf1bba8978a8dcb2748208c982e26a50b9/app/controllers/administrate/application_controller.rb#L100
module Admin
class AuthorsController < Admin::ApplicationController
def resource_params
params.require(:author).permit(
permitted_attributes,
social_links_attributes: [
:id,
:value,
:title
]
)
end
end
end
Would love to see nested forms as part of Administrate.
@nburkley Your answer got me going and I devised a slightly less "invasive" approach. In the Dashboard for the model in question, you can define permitted_attributes. I now have cocoon working flawlessly! Here is a peek at my formatting
def permitted_attributes
[ :question, :note, :kind, :has_sub, :parent_id, answers_attributes: [:id, :answer, :question_id, :_destroy]]
end
@airjoshb that's a great approach! I'll take a crack at officially supporting & documenting that.
@nburkley and @airjoshb - can you post the .html.erb files that you generated for the nested fields? Thanks!
ok, I managed to recreate this in one of my own apps. I think there are some things we can do to make this process more automated, with less user input. I'm hopeful that we can build out some kind of Administrate::Field::NestedHasMany class that handles all of the permitted attribute gotchas, and intelligently creates form templates based on a list of attributes.
@graysonwright Here are my files:
fields/nested_answer_field/_form.html.erb
<div class="field-unit__label">
<%= f.label field.attribute %>
</div>
<div id="answers">
<%= f.fields_for field.attribute do |a| %>
<%= render 'answer_fields', f: a %>
<% end %>
<div class="links">
<%= link_to_add_association 'add answer', f, field.attribute %>
</div>
</div>
and admin/application/_answer_fields.html.erb
<div class="nested-fields">
<div class="field">
<%= f.label :answer %>
<%= f.text_field :answer, autofocus: true %>
</div>
<%= link_to_remove_association "remove answer", f %>
</div>
@airjoshb thanks!
@graysonwright I haven't added nested forms yet, just added an MVP with allowed editing some child values that we build on create. Looks like @airjoshb has you covered anyway.
In #476, we decided on a plugin structure for new field types. Nested has_many forms are a good candidate for a plugin, so I extracted this code out to https://github.com/graysonwright/administrate-field-nested_has_many.
It's rough but functional. PRs are welcome on that repository. If we get it polished enough and it turns out to be useful enough, we can absorb it into this core repository.
@nburkley @airjoshb thanks for your help!
nice, thanks @graysonwright!
very cool. Thanks! @graysonwright
nice! @graysonwright, can this be used with paperclip as well? I'm trying to do nested pictures for products.
Btw, thanks everyone for your inputs and comments. It's helped to solve many issues I run to when implementing administrate.
Also, I think this line #7 require "administrate/field/image" needs to be removed. It looks like image has been moved to a plugin. thanks again!
Most helpful comment
In #476, we decided on a plugin structure for new field types. Nested has_many forms are a good candidate for a plugin, so I extracted this code out to https://github.com/graysonwright/administrate-field-nested_has_many.
It's rough but functional. PRs are welcome on that repository. If we get it polished enough and it turns out to be useful enough, we can absorb it into this core repository.
@nburkley @airjoshb thanks for your help!