Reputation: 9415
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">‹</a><a class="carousel-control right" href="#carousel-<%[email protected]_id%>" data-slide="next" style="display:none">›</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
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