Is there any complication of using IFrames in Rails? - ruby-on-rails

I am trying to preview a PDF in my rails application. The file sits in the uploads folder and not in the public or assets folder. So I have a action in my controller called preview which uses send_file.
I have a before filter for preview called check_shared which checks if the user is allowed to view the file or not.
When this entire workflow works for a simple image preview where I just use an image_tag to render the image, it fails to work with an IFrame. An error arises in the check_shared private action which says that "current_user"( I am using Devise) is not a valid method.
Does the controller action somehow lose it's scope in the Iframe?
Here is the view:
<%= image_tag preview_myfile_path(#myfile) %>
<iframe src="/pdfjs/web/viewer.html?file=<%= preview_myfile_path(#myfile) %>" id="pdf_frame" style="border: 0" width="100%" height="1000" frameborder="0" scrolling="no"></iframe>
Here is the preview action:
def preview
# Introducing choosepath, to reduce double render errors.
send_file choosepath(#myfile)
end
Here is the before action:
def check_shared
puts "inside check_shared"
#myfile = Myfile.find(params[:id])
if current_user.id == #myfile.user_id
puts "owner!"
else
flash[:notice] = "You do not have permission to access this file!"
redirect_to root_path
end
end

Related

How can I add a download link to files in my Digitalocean Space in my Rails app?

I'm trying to create a download link/button in my Rails app so that users can download files from my Digitalocean Space. I want to be able to click a download button on my show page and download the file. Here is what I've tried s far:
samples_controller.rb
def show
#sample = Sample.find(params[:id])
data = open(#sample.audio_url)
#sample_download = send_data data.read, filename: #sample.audio.metadata["filename"], type: #sample.audio.metadata["mime_type"], disposition: 'inline'
end
show.html.erb
<%= link_to "Download Sample", #sample_download %>
When I load the show page this opens a page that plays the audio file. What I want is to see my show template as normal and be bale to click a link to download the file. Maybe I should have a separate download_sample method, I'm not sure.
You can trigger download on browser side using the download attribute on an <a> tag.
All you need is something like <a href="http://linktofile.com/audio.mp3" download>Download</a> and user can click on the link to download.
Using the Rails helper, you can do <%= link_to "Download", #sample.audio_url, download: true %>
Hi for content from another website make sure the link is a direct link.
If the data you want to download is from active storage take a look at rails_blob_path (here)
.
In your model
Class Sample < ApplicationRecord
has_one_attached :data
end
In your controller
class SampleController < ApplicationController
def show
#sample = Sample.find(params[:id])
#sample_download = rails_blob_path(#sample.data, disposition: 'attachment')
end
end
In your views
<%=link_to "Download", #sample_download %>

How to display the variant of an image with Active Storage in a JS box?

In my view, I can display my file attached to the model with Active Storage in a popup like this:
<%= image_tag #image.variant('small') %>
It's working well.
The problem is when I want to use a variant in the link:
<%= image_tag #image.variant('small') %>
The variant code used is:
file.variant(resize:size).processed.service_url
The link seems to be good, but when I click the image, the image is not opened in my JS popup as before but opened in a new browser window. This is very strange.
I shortened the link.
https://bucket.s3.eu-west-3.amazonaws.com/variants/MmsLY3rf8yR9/38a77a69d170464c472f6d36fb3fbc28b284af0cadaa533?response-content-disposition=inline%3B%20filename%3D%22chateau.jpeg%22%3B%20filename%2A%3DUTF-8%27%27chateau-lynch.jpeg&response-content-type=image%2Fjpeg&Signature=29fe7d85fe369ea2335fa8b333d4868d8c2f2c22e1efe
Is-it a "content-disposition" issue ?
Well, this is what I did:
In my Image model, I added an action and used the rails_representation_url() method from url_helpers:
include Rails.application.routes.url_helpers # need this for
include Rails.application.routes.url_helpers
def get_variant(version="high", disposition="attachment")
variant = file_variant(version)
return rails_representation_url(variant, only_path: true, disposition: disposition)
end
In my html, I can call my method with attachment disposition:
<a href="<%= #image.get_variant('high', 'attachment') %>" rel="example_group">
I can also download the image variant directly from my controller:
def download
redirect_to #image.get_variant('high', 'attachment')
end
If you want to only display the variant in the browser window, you can use 'inline':
redirect_to #image.get_variant('high', 'inline')
Not sure it's the best option, but it works.

How to return flash to page from remote controller rails?

I am using remote:true as the option in a rails form. I happily posts to a remote controller. I was wondering if it is possible to return a flash (something like flash.now[:success]) to the pager with the form on.
Many thanks
in your controller's action
def my_action
//.....
flash[:success] = "data saved successfully!"
end
in your my_action.js.erb file
<%if flash[:success].present?%>
$('#header_id').html("<%= j render 'your_flash_message_partial'%>");
<%end%>
header_id is id of div where you commonly display your your flash message.
your_flash_message_partial is complete path of your partial of flash message page

Using Panda (pandastream) Video to show all videos in Index Action

I'm using PandaVideo (http://www.pandastream.com/docs/integrate_with_rails) to upload videos in my Rails app. I'm having trouble taking the code from the docs at Panda and Heroku to relate it to the index action to show ALL of the videos, both on the Video's controller index action and on the User's profile to show each user's videos.
Here is the code that they give to find and show the video on the Video's SHOW action:
#video = Video.find(params[:id])
#original_video = #video.panda_video
#h264_encoding = #original_video.encodings["h264"]
then on the show view, I reference the video based on the last variable #h264_encoding
This works nicely. Now, I need to somehow take this code and use it to show all videos on a single page. For this example, let's show all of a particular user's videos on their page.
def show
#user = User.find_by(username: params[:username])
# not sure what goes here to find that user's videos (from Panda).
# If i were just using paperclip for instance, I could easily write:
#videos = #user.videos # but I need to use the Panda (the #h264_encoding variable) to find the video.
end
maybe this is useful...here is part of the video model
def panda_video
#panda_video ||= Panda::Video.find(panda_video_id)
end
I hope I've provided enough code. If not please let me know and I'll add more. Again, I'm trying to show all of a particular user's videos from PandaStream.
Not sure if I'm missing something, but why wouldn't it be as simple as this:
def index
#videos ||= Video.all
end
As far as your show, I see nothing wrong with this:
def show
#user = User.find_by(username: params[:username])
#videos = #user.videos
end
Then in your view something like the following:
<%= #videos.each do |video| %>
<% h264_encoding = video.panda_video.encodings["h264"] %>
<video id="movie" width="<%= h264_encoding.width %>" height="<%= h264_encoding.height %>" preload="none"
poster="<%= h264_encoding.screenshots.first %>" controls>
<source src="<%= h264_encoding.url %>" type="video/mp4">
</video>
<% end %>
You are simply referencing Panda's API to retrieve the information relating to an upload, however you handle all the relationships and the User and Video models.
Let me know if I'm missing something, as it seems you are on the right track.

What happend after send_file in Rails controller?

In the index view, there is a link to download file:
<%= link_to filename, listing_download_path(:file => filename) %>
In the controller:
def download
pathname = File.join(USER_FOLDER, params[:file])
if File.file?(pathname)
send_file pathname
end
end
end
When the user click download, a file download popup is shown. What's happen after the file is downloaded? Does rails just sit there and do nothing more? If I delete the send_file line, dwonload.html.erb will be rendered. Does send_file skip view rendering?
What if I want to show soemthing like "You have downloaded ..."?
The send_file is a render itself. You could use the approach proposed in this question:
Rails: send_file never renders page or DoubleRender error
Basically your download link will send to a "success" view, from which you call the download file method automatically.

Resources