I am trying to download the data stored amazon s3 bucket using paperclip and aws-sdk gem. Object is publicly accessible.
I am having a method in my controller where I intend do download the data directly.
def method_where_downloading_happens
code for finding url from params
send_file "ModelName.attached_file.url"
end
#Tried both with static and dynamic url.
I am getting following error
NoMethodError: undefined method `send_file for main:Object
However if I use :-
send_file open(ModelName.attached_file.url)
Then a file is downloaded but it's format is binary i.e. windows can't identify the file_type.
Please help how do I provide direct download when the person hits the link.
You can try this:
#In your environment.rb require 'open-uri'
require 'open-uri'
#As send_data will work in controller, so in your controller
def index
data = open(params[:file])
send_data data, :filename => params[:name], ...
end
Related
I'm working on a small app that uses CarrierWave for image uploading, but (for reasons that are a bit long and not really relevant) we have to stop using CarrierWave and start uploading images with our own custom requests to different cloud storage services.
But I still need to have the URLs to images that were already uploaded using CarrierWave, and I won't have access to the image_url method once I unmount the CarrierWave uploader, so I want to save all the urls to a new column on my model, and to have that migration be as optimized as possible.
I've searched for ways to access directly the url from the database (I mean, CarrierWave has to store that somewhere) but no luck so far.
I could do something like this (business_image is the column that the uploader is mounted on, image_url is the new column where I want to store the url):
def change
add_column :business_cards, :image_url, :string
BusinessCard.all.each do |bc|
bc.update(image_url: bc.business_image_url)
end
end
But that is obviously not optimized at all since it loads all business cards and updates them one by one. Is there a way to do it in a single SQL statement?
(I'm using Rails 5.1.4, PostgreSQL 10.3 and carrierWave 1.2.1)
One way would be too use batch function and update record in batches, you can use transaction so that if there are any errors the changes would be rolled back.
def change
add_column :business_cards, :image_url, :string
BusinessCard.find_each(batch_size: xxx) do |bc|
ActiveRecord::Base.transaction do
bc.update(image_url: bc.business_image_url)
rescue => e
raise ActiveRecord::Rollback
end
end
end
Hope it helps!!
I am using rails 5 and grape gem for building my application. Now I have a requirement of generating a PDF and send back to the response using grape endpoint. I am using wicked_pdf gem and wkhtmltopdf-binary for generate PDF. But I am facing the issue of undefined method 'render_to_string'.
I have tried various way to resolve it. but couldn't find any solution.
Below is my code snippet
API Endpoint:
module Endpoints
class GeneratePdf < Grape::API
get do
users = User.all # I want this users list in my PDF
pdf = WickedPdf.new.pdf_from_string(render_to_string('users/index.html.erb')) # placed in app/views/users/pdf.html.erb
# some code here for send pdf back to response
end
end
end
Gemfile:
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
Config > initializers > mime_types.rb
Mime::Type.register "application/pdf", :pdf
Grape::API, don't have a render_to_string method that you can call on it, unlike a typical Rails controller. You should be able to replace that with something similar to this:
require 'erb'
binding_copy = binding
binding_copy.local_variable_set(users: User.all)
template = File.open(Rails.root.join('app/views/users/index.html.erb))
string = ERB.new(template).result(binding_copy)
pdf = WickedPdf.new.pdf_from_string(string)
I have migrated from Paperclip to Carrierwave, and using Carrierwave_direct to upload images directly to S3.
class User < ActiveRecord::Base
mount_uploader :profile_picture, ProfilePictureUploader, :mount_on => :profile_picture_file_name
So, in my schema, I don't have column profile_picture but profile_picture_file_name in my users table.
This creates problem when I am trying to create the #uploader instance variable
class ProfilePictureController < ApplicationController
def show
#user=current_user
#uploader = #user.profile_picture_file_name
#uploader.success_action_redirect = crop_url
end
This throws an error, when a user is trying to upload the Profile Image,
undefined method `success_action_redirect=' for nil:NilClass
I guess this could fix it:
#uploader = #user.profile_picture
I have a little problem with paperclip saving the data passed through the form...
If I'm trying to save the record with .save() it won't save.. When I look in the server/log there are no errors or warnings for the paperclip gem :-/
# trying to save the record with save() -- not working :-/
def create
#baan_import = BaanImport.new(params[:baan_import])
if #baan_import.save
redirect_to(baan_imports_url)
else
render 'new'
end
end
Server-log: (using .save() in controller)
https://gist.github.com/1327347
I just don't get it why it's working if I'm using .create instead of .save()
# trying to save the record with Model.create() -- working!
def create
#baan_import = BaanImport.create(params[:baan_import])
redirect_to(baan_imports_url)
end
Server-log: (using .create() in controller)
https://gist.github.com/1327359
Can some one explain me why it's working with create and not with save??
Thanks,
Michael
Can you show us the BaanImport model. My first guess is you're possibly missing baan_upload in attr_accessible on your model, and as a result, Rails will not let you mass assign the file parameter for upload.
Can you also confirm (would appear as though it's properly set up) that your form has html => {:multipart => true} as an option?
I've tried including ActionView::Helpers::AssetTagHelper and a bunch of variants of that, but I always get an error saying NameError: undefined local variable or methodconfig' for main:Object`
Updated with more info
I need to be able to reference a resource that is stored on different servers depending on the environment. On my development machine it will be referenced at localhost:3000, on the production server it will be at one CDN address, and on staging it will be at yet another. Obviously we want to test this rake task locally first, then on staging and then finally on staging so the rake tasks needs to be able to generate URLs based on the asset host configuration variable. I actually went so far as to create an ApplicationHelper method called asset_path to do this in my views, but it's basically just an alias for compute_asset_host. However, if I include ApplicationHelper in my rake task and call asset_path it complains that compute_public_path is undefined, and then if I include (or extend) ActionView::Helpers::AssetTagHelper it complains about undefined local variable or method 'config' for main:Object from inside compute_asset_host. So I need to somehow invoke whatever instantiates the config container that is used by ActionView::Helpers so that compute_asset_host can return the proper URL based on the environment.
It is ugly and I try to get around doing things like this but...
namespace :test do
def view(url_options = {}, *view_args)
view_args[0] ||= ActionController::Base.view_paths
view_args[1] ||= {}
view = ActionView::Base.new(*view_args)
routes = Rails::Application.routes
routes.default_url_options = {:host => 'localhost'}.merge(url_options)
view.class_eval do
include ApplicationHelper
include routes.url_helpers
end
assigns = instance_variables.inject(Hash.new) do |hash, name|
hash.merge name[1..-1] => instance_variable_get(name)
end
view.assign assigns
view
end
task :it => :environment do
param = ""
puts ">>> compute_asset_host returns: [#{view.send("compute_asset_host", param)}]"
end
end
... may start you in a direction to solve the problem you are having.
PS: I found the view method here: https://gist.github.com/592846
This is what I do
task :it => :environment do
include ActionView::Helpers
include ApplicationHelper
# your code here
end