scientiffic
scientiffic

Reputation: 9415

redirect_to create.js.erb of another controller

I have a Rails app where I create a thumbnail image when the user embeds a video (so I have an Image model and a Video model).

I have successfully created a new image through the video controller. Upon creating the video, I'd like to redirect to the image/create.js.erb file for the Image controller, passing in the newly created thumbnail image for the video.

The images/create.js.erb file does a bunch of different things to render an updated page, so I don't want to repeat the code in my video/create.js.erb file.

This is what I have:

video_controller:

  # POST /videos
  def create
    # need to validate
    @video = Video.create(params[:video])
    # get the thumbnail image
    thumbnail = @video.thumb_url
    logger.debug "thumbnail video: #{thumbnail}"
    @video.update_attributes(:thumbnail_url => thumbnail)

    # create a new image record for the thumbnail
    position = Step.find(@video.step_id).images.count # set the position of the added thumbnail to the last
    @newImage = Image.new(:step_id=>@video.step_id, :image_path=> "", :project_id=>@video.project_id, :saved=> true, :position=>position)
    @newImage.update_attributes(:remote_image_path_url => thumbnail)
    @newImage.save

    respond_to do |format|
      if @video.save        
        format.js {redirect_to :controller=> "images", :action=>"create", :image=> @newImage}
      else
        format.json { render :json => @video.errors, :status => :unprocessable_entity }
      end
    end
  end

When I embed a video, it returns the following logs:

  SQL (0.8ms)  INSERT INTO "images" ("caption", "created_at", "image_path", "position", "project_id", "saved", "step_id", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id"  [["caption", nil], ["created_at", Fri, 05 Jul 2013 17:09:16 EDT -04:00], ["image_path", "default.jpg"], ["position", 0], ["project_id", 108], ["saved", true], ["step_id", 523], ["updated_at", Fri, 05 Jul 2013 17:09:16 EDT -04:00]]
   (1.5ms)  COMMIT
   (0.1ms)  BEGIN
   (0.3ms)  COMMIT
   (0.3ms)  BEGIN
video id: O9k-MsfIkMY
   (0.3ms)  COMMIT
Redirected to http://0.0.0.0:3000/images?image=1031
Completed 302 Found in 2084ms (ActiveRecord: 7.4ms)

Started GET "/images?image=1031" for 127.0.0.1 at 2013-07-05 17:09:17 -0400
Processing by ImagesController#index as JS
  Parameters: {"image"=>"1031"}
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 5 LIMIT 1
  Image Load (0.8ms)  SELECT "images".* FROM "images" 
  Rendered images/index.html.erb within layouts/application (0.1ms)
Completed 200 OK in 50ms (Views: 43.8ms | ActiveRecord: 1.2ms)

So it is not correctly redirect to the image/create.js.erb file. How can I do this?

This is my images/create.js.erb file so you have an idea of the types of actions I don't want to repeat in my video/create.js.erb file:

<% if @image.new_record? %>
  alert("Failed to upload image: <%= j @image.errors.full_messages.join(', ').html_safe %>");
<% else %>

  $("#videoEmbedModal").modal('hide');

  var stepImagesCount = $('.image').length;

  <% #add image to image gallery %>
  $("#images").append("<%= j render(@image) %>");

  // load the slideshow if we're uploading the first image
  if (stepImagesCount == 0){
    // move image form to the right gallery
    $('.rightGallery').append($('#new_image'));

    // add photo to carousel 
    $('.carousel-inner').append('<div class="item active"><a class="fancybox" href="<%[email protected]_path_url%>" rel="gallery <%[email protected]_id%>"> <%=image_tag(@image.image_path_url(:preview), :width => "100%", :id=>@image.id)%></a></div>'); 
    addImageButton("right");
    imageReset = true;
    $('#blankPhoto').remove();
    $('.mainPhoto').show();
  }
  else{
    // add photo to carousel 
    $('.carousel-inner').append('<div class="item"><a class="fancybox" href="<%[email protected]_path_url%>" rel="gallery <%[email protected]_id%>"><%=image_tag(@image.image_path_url(:preview), :width => "100%", :id=> @image.id)%></a></div>');
    $('.carousel').append('<a class="carousel-control left" href="#carousel-<%[email protected]_id%>" data-slide="prev" style="display:none">&lsaquo;</a><a class="carousel-control right" href="#carousel-<%[email protected]_id%>" data-slide="next" style="display:none">&rsaquo;</a>');
  }

  // get step ID from carousel
  var stepID = get_carousel_ID();
  setCarousel(stepID, stepImagesCount+1);

  // remove upload
  $('.upload').remove();

  // scroll to the bottom of the thumbGallery to show recently uploaded image
  var thumbGalleryDiv = document.getElementById("images");
  thumbGalleryDiv.scrollTop = thumbGalleryDiv.scrollHeight;

<% end %>

function get_carousel_ID(){
  var carousel_id = $('.carousel').attr('id');
  var slashIndex = carousel_id.indexOf('-')+1;
  var step_id = carousel_id.substring(slashIndex, id.length)
  return step_id
}

Upvotes: 0

Views: 1288

Answers (1)

GoGoCarl
GoGoCarl

Reputation: 2517

I believe you can do:

render 'images/create'

Instead of And it will achieve the same effect.

However, if you are concerned about DRY code, there are other alternatives; you could move the code you don't want to repeat into another partial, and simply call that partial from the views. This is probably a cleaner, more modularized solution because you aren't doing anything out-of-the-norm in the controller.

Hope that helps.

Upvotes: 2

Related Questions