views:

35

answers:

1

I currently have two models: Campaigns and Videos. Videos belongs to Campaigns and a Campaign has many Videos. In my Campaign form I want to be able to add Videos that have no parent and also be able to remove Videos that belong to the selected campaign. I came up with using two separate multiple selection lists for this. One list has all orphaned Videos and the other has all videos that belong to the selected campaign. That way a user and just select which videos to add and remove. I've run into trouble when trying to create the logic for adding and removing Videos from the selected Campaign in my "update" and "create" methods. I imagine that somehow I would need to take an array from each the selection lists and run a loop that adds and a loop that removes the selected videos in each form.

I'll post what I have so far from my form and my controllers:

Campaigns Controller - Update method:

  def update
    if @campaign.update_attributes(params[:campaign])
      unless request.xhr?
        flash[:notice] = "'#{@campaign.title}' was successfully updated."
      else
        flash.now[:notice] = "'#{@campaign.title}' was successfully updated."
      end
      unless from_dialog?
        unless params[:continue_editing] =~ /true|on|1/
          redirect_to admin_campaigns_url
        else
          unless request.xhr?
            redirect_to :back
          else
            render :partial => "/shared/message"
          end
        end
      else
        render :text => "<script type='text/javascript'>parent.window.location = '\#{admin_campaigns_url}';</script>"
      end
    else
      unless request.xhr?
        render :action => 'edit'
      else
        render :partial => "/shared/admin/error_messages_for", :locals => {:symbol => :campaign, :object => @campaign}
      end
    end
  end

Campaign Form Partial:

<%= error_messages_for :campaign -%>
<% form_for [:admin, @campaign] do |f| -%>

  <div class='field'>
    <%= f.label :title -%>
    <%= f.text_field :title, :class => 'larger' -%>
  </div>

  <div class='field'>
    <%= f.label :description -%>
    <%= f.text_area :description, :rows => 20, :cols => 140, :class => 'wymeditor' -%>
  </div>

  <div class='field'>
    <%= f.label :date -%>
    <%= f.date_select :date -%>
  </div>

  <div class='field'>
    <%= f.label :videos_in, "Add Videos" -%>
    <%= f.collection_select(:title, @orphanedVideos, :id, :title, {}, {:multiple => true}) -%>
  </div>

  <div class='field'>
    <%= f.label :videos_out, "Remove Videos" -%>
    <%= f.collection_select(:title, @campaignVideos, :id, :title, {}, {:multiple => true}) -%>
  </div>

  <div class='field'>
    <%= f.label :preview -%>
    <%= render :partial => "/shared/admin/image_picker", :locals => {
      :f => f,
      :field => :preview_id,
      :image => @campaign.preview,
      :toggle_image_display => false
    } %>
  </div>

  <%= render :partial => "/shared/admin/form_actions", :locals => {:f => f, :continue_editing => false} %>
<% end -%>

I'm not sure if the collection_select's are setup properly (though they do display correctly on the form). Any pointers would be appreciated.

Thanks for looking!

A: 

I actually figured out a nice way using check boxes. So for the videos_out and vidoes_in sections I used the following code:

<% unless @orphaned_videos.empty? %> <%= f.label :videos_in, "Add Videos" -%>

    <% @orphaned_videos.each do |video| %>
  • <%= image_fu video.preview, :grid %> <%= check_box_tag "campaign[video_ids][]", video.id, nil %> <%= video.title %>
  • <% end %>
<% end %>

<% unless @campaign_videos.empty? %> <%= f.label :videos_in, "Remove Videos" -%>

    <% @campaign_videos.each do |video| %>
  • <%= image_fu video.preview, :grid %> <%= check_box_tag "campaign[video_ids][]", video.id, true %> <%= video.title %>
  • <% end %>
<% end %>

This should work with your default controller settings, though you'll want to make sure you take care of the scenario when no items are checked by putting this in your controller:

#If no checkboxes checked must create an empty array (whole reason for this function override)
params[:campaign][:video_ids] ||= []
jklina