Ask A Question

Notifications

You’re not receiving notifications from this thread.

Flexible Nested Attributes

Terence Devine asked in Gems / Libraries

I'm working on a practice "Magazine" application, that has Issues with nested attributes of Articles, which has multiple nested attributes that are Content Blocks, which can be one of several types of Models (ie: Text Field, Image Upload, Image Gallery, etc).

Example
Issue

  • Article
  • - Content Block ( Text Field )
  • - Content Block ( Image )
  • - Content Block ( Text Field )
  • - Content Block ( Image Gallery )

In my head I've been referring to these Content Blocks as 'Flexible Nested Attributes'... not sure if theres any proper terminology for this?

I am using the Cocoon Gem for this.

I tried adding 'order_number' to Models, and just adding the two 'link_to_add_association' links as well as the respective fields for the form (see below) - and then ordering the two content types in the controller (see below-er)... which works, except for when I go to edit the form, and it orders all the items by their content type.

Do you know if the Cocoon gem can be used in this way? Or is there another gem I should be using (such as ActiveForm Gem)? Or if this is all wrong and maybe I should approach it some other way!?

Any help is greatly appreciated! Thanks!

= simple_form_for @recipe, html: { multipart: true } do |f|
    - if @recipe.errors.any?
        #errors
            %p
                = @recipe.errors.count
                Prevented this recipe from saving
            %ul
                - @recipe.errors.full_messages.each do |message|
                    %li= msg

    = f.input :title
    = f.input :description
    = f.input :image

    %h3 Contents
    #contents
        = f.simple_fields_for :images do |image|
            = render 'image_fields', f: image
        = f.simple_fields_for :textarea do |textarea|
            = render 'textarea_fields', f: textarea
        = link_to_add_association 'Add image', f, :images
        = link_to_add_association 'Add textarea', f, :textarea

    = f.button :submit
    def show
        @contents = @recipe.textarea + @recipe.images
        @contents = @contents.sort_by(&:order_number)
    end
Reply

sorry for the multiple posts - I keep getting errors whenever I try to post / comment on threads!?

Reply

I've been having a couple hiccups with the new version of Passenger and it's connection to the database. Going to revert back to Puma for a bit and that should solve the errors posting.

I think Cocoon technically calls these "nested forms" since you're dynamically adding new form fields for new objects.

Might need to correct me if I'm misunderstanding the issue here, but this is what I think is happening:
One thing that might be happening is that when the page re-renders your form actually renders using the @recipe and the assocations on it without using @contents variable. I think you probably have two options there. Either adding a scope into the association to order the contents or seeing if you can pass in @contents as the variable to use for rendering the fields.

Reply

Yes - Cocoon calls them "nested forms" - but the difference I have here is that I need to have multiple models that are all combined / contained within one larger group (content blocks)... which is why I decided to throw the word 'Flexible' in there!

I haven't had a chance to watch this yet (bouncing between tasks at work) but does this tutorial give some insight on how to handle this sort of task? Seems the 'merge' might be exactly what I'm looking for to combine these models.

https://gorails.com/episodes/named-scopes-with-activerecord-merge

I'll be sure to watch this screencast once I'm back from work, but wanted to make a post while it was fresh in my mind. Thanks again!

Reply

I'm finally getting back around to this - and am looking more into adding scope into the association, but am new to the topic and am having trouble finding much help besides active record documentation.

Would this type of scope be added to each of the different models that makes up the 'Content Blocks'? Sorry - just new to scope and not sure where to start!?

Thanks again!

Reply

It's been a while since I read this. :)

What I was suggesting with scopes on the association (I think) was something like this:

has_many :contents, -> { order(:order_number) }

Most people don't realize you can pass a lambda into associations like this to add scopes and other additions to the query. I always seem to forget it exists, but it can be really helpful for things like this.

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 82,329+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more.

    © 2024 GoRails, LLC. All rights reserved.