0

I have a nested form for a user, portfolios, and photos. Basically a user can create a portfolio by uploading photos in ANOTHER FORM. However, then I want to give them a chance to create a new portfolio, by selecting some photos from the current portfolio they are viewing, and have the method resubmit in PortfolioController create a new portfolio for them. The models are:

class User < ActiveRecord::Base
    has_many: portfolios
end

class Portfolio < ActiveRecord::Base
    has_many: photos
    belongs_to: user
end


class Photo < ActiveRecord::Base
    belongs_to: portfolio

    attr_accessor :move
end

The controller is:

class PortfolioController < ApplicationController
    //... some generic code

    def resubmit
        // This is where I need help
    end

    def display
        @userPortfolio = Portfolio.where(:id => params[:uid]).first
    end
end

and the view is:

<%= simple_form_for @userPortfolio, :url => {:action => resubmit} do |f|%>
    <%= f.label current_user.name %>
    <% @images = @userPortfolio.photos %>
    <% @images.each do |anImage| %>
        <%= f.fields_for :anImage do |ff| %>
            <%= ff.checkbox :move, :id => "move_#{anImage.id}" %><%=ff.label :move, "Move image #{anImage.name} to new portfolio?" %>

        <% end %>
    <% end %>

    <%= f.submit "Create new portfolio" %>
<% end %>

Basically once the user hits submit I want the method resubmit to create a new portfolio with a collection of new photos that are the same as the photos selected. That is, I want to create 1 new record of portfolio and several new records photo, as many as the user has selected, based on the properties of the photos the user selected, so I need to access the records that represent the selected photos. How do I access all the photos the user has selected? I can't simply create a finite set of checkbox controllers on the form since the number displayed depends on the number of photos in the current portfolio.

2 Answers 2

1

Use the gem nested_form or cocoon to make the elements dynamic. On the backend use the selected items to create entries for the new portfolio.

Sign up to request clarification or add additional context in comments.

2 Comments

can you a give a more detailed, code containing answer? I looked at nested_form documentation and it doesn't show how to access things on the back end
It all happens like magic once your models are configured. :) This project might help github.com/ryanb/complex-form-examples/tree/nested_form & this railscast youtube.com/watch?v=-WJUaCI-SWg
0

Okay, so it seems what I was trying to do was fairly simple after all. No need for nested_form, the simple_form does just as well. But I'm sure nested_form (as Tory SK suggested) does the trick as well. The major point was adding attr_accessor: to the code.

Basically the code is as follows:

class User < ActiveRecord::Base
    has_many: portfolios
end

class Portfolio < ActiveRecord::Base
    has_many: photos
    belongs_to: user

    attr_accessor: photos_attributes // This is an important piece of code
end


class Photo < ActiveRecord::Base
    belongs_to: portfolio

    attr_accessor :move
end

Then I simply changed the form as follows (notice the additional :pid => params[:pid] so that I can figure out in resubmit which portfolio I need to access IF I need to access it):

<%= simple_form_for @userPortfolio, :url => {:action => "resubmit", :pid => params[:pid]} do |f|%>
    <%= f.label current_user.name %>
    <% @images = @userPortfolio.photos 
       i = 0
    %>
    <%= f.fields_for :images do |ff| %>
            <% anImage = @images[i] %>
            <%= ff.checkbox :move, :id => "move_#{anImage.id}" %><%=ff.label :move, "Move image #{anImage.name} to new portfolio?" %>
            <% i = i+1%>
    <% end %>

    <%= f.submit "Create new portfolio" %>
<% end %>

And when you hit submit and send the form to resubmit, the params dictionary contains the following:

{"utf8"=>"✓",
 ... more parameters
 "portfolio"=>{"photos_attributes"=>{"0"=>{"move"=>"0",
                                           "id"=>"1"},
                                     "1"=>{"move"=>"0",
                                           "id"=>"2"},
                                     ...

                                     "4"=>{"move"=>"0",
                                           "id"=>"5"}}},
 "commit"=>"Submit Job",
 "pid"=>"1"}

Now I can just iterate through the checkboxes and compare them to all the photos that belong to the current portfolio in resubmit

def resubmit
    @myImages = Portfolio.where(:id => params[:pid]).photos
    // iterate through each image and use a counter to access 
    // the dictionary elements to see if they were checked
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.