Rails - Serve static CSV file as assets in Development with Thin - ruby-on-rails

I'm simply trying to write to a CSV file in dev with thin, but I am continually getting an error that says
No such file or directory - http://localhost:3000/assets/tplan_log.csv
However, my config looks like this:
development.rb
config.serve_static_assets = true
And my controller looks like this:
def csv
#this returns a valid path
log_path = view_context.asset_path 'plan_log.csv'
#error occurs here
CSV.open(log_path) do |csv|
csv << ["row","row1","row2"]
end
respond_to do |format|
format.js {render json: #diaggroup.errors, status: :unprocessable_entity}
end
end
Rails 3.2.12
Edit: To clarify, I'm looking for an answer on how to serve this file in development so that it is accessible. I know it's being served with asset pipeline, but there is no get method associated with it, so it's not able to be accessed.

This ended up being an issue with reference.
I was using a reference such as:
http://path/to/file.jpg
Rails wants:
/path/to/file.jpg

Related

Rails 6.1.4 Wicked PDF

I am attempting to implement Wicked PDF (https://github.com/mileszs/wicked_pdf/) in a Rails 6.1.4 project and am continually getting the following error messages on the console.
My configuration is as simple as it gets. The controller looks like:
class Api::V1::ProductsController < Api::V1::BaseController
def datasheet
#product = Product.active.friendly.find params[:id]
respond_to do |format|
format.pdf {
render "products/datasheet", pdf: "datasheet-#{#product.name}"
}
end
end
end
and the datasheet.haml file looks like:
%html
%head
%body
= "This and that"
The file encoding for the datasheet.haml is UTF-8, but this shouldn't matter because the text contains no special characters.
The Gemfile has both wicked_pdf and wkhtmltopdf-binary.
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
I have executed the command rails generate wicked_pdf and it did generate the wicked_pdf.rb initializer, as expected.
I have tried putting Mime::Type.register "application/pdf", :pdf into the mime_types.rb file, but expect that this wouldn't matter because I am running Rails 6.
The response generated is:
We have another application running Rails 6.1.4 using wicked_pdf in, "ahem...", the exact same way successfully. Obviously something is different, I just cannot find out what...
Any suggestions on what I am overlooking? Your help is much appreciated!

Wicked pdf, failed to load PDF document

I am trying to implement the gem wicked_pdf . After initial difficulties (fatal error (exception reentered)), I managed to start the server. I set up a pdf with the content "Hello world" for the test, but every time I want to open it, I get a "failed to load PDF document" notification
Controller
def index
respond_to do |format|
format.html
format.pdf do
render pdf: "index.pdf.haml",
layout: 'pdf.html.haml',
page_size: 'A4',
disposition: 'inline'
end
end
end
index.pdf.haml
Hello world
config/initializers/wicked_pdf.rb
# WickedPDF Global Configuration
#
# Use this to set up shared configuration options for your entire application.
# Any of the configuration options shown here can also be applied to single
# models by passing arguments to the `render :pdf` call.
#
# To learn more, check out the README:
#
# https://github.com/mileszs/wicked_pdf/blob/master/README.md
class WickedPdf
module PdfHelper
remove_method(:render)
end
end
WickedPdf.config = {
# Path to the wkhtmltopdf executable: This usually isn't needed if using
# one of the wkhtmltopdf-binary family of gems.
# exe_path: '/usr/local/bin/wkhtmltopdf',
# or
# exe_path: Gem.bin_path('wkhtmltopdf-binary', 'wkhtmltopdf')
# Layout file to be used for all PDFs
# (but can be overridden in `render :pdf` calls)
# layout: 'pdf.haml',
# Using wkhtmltopdf without an X server can be achieved by enabling the
# 'use_xvfb' flag. This will wrap all wkhtmltopdf commands around the
# 'xvfb-run' #command, in order to simulate an X server.
# use_xvfb: true,
}
config/initializers/mime_types.rb
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
Mime::Type.register "application/pdf", :pdf
Link to Screenshot: https://drive.google.com/file/d/1ujt8ANq16SrmSHJk45APMXXxm1l5q5ic/view?usp=sharing
Ok, so I downgraded wicked_pdf to version 1.4.0 and I removed:
class WickedPdf
module PdfHelper
remove_method(:render)
end
end
From config/initializers/wicked_pdf.rb, and now it works.

compile in Rails 6 Webpacker doesn't make changes to send_data with methods defined in model

I recently upgraded to Rails 6 with webpack. This is when I started to notice this issue. I have a send_data method in a controller that works with either a csv or pdf (Prawn) format. Currently experiencing this issue with a csv.
In development, I made a method for self.to_csv in models/user.rb and used it to download some data into a CSV file. I deployed the file to my production server. And downloaded the file there.
Then I made a change to the columns that would be printed in that file. I saw the changes immediately in development. I deployed these changes to production, but still get the old columns. I checked the files on the server and they have the updates.
In Rails 5, I would see these changes immediately in production, too. Is there a way I can speed the server along here? Re-cache the files? Etc.
Here are my files.
In controllers/users_controller.rb:
def index
respond_to do |format|
format.csv {
send_data User.all.to_csv
}
end
end
In models/user.rb:
def self.to_csv
attributes = %w{first_name last_name id}
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |obj|
csv << [obj.first_name, obj.last_name, obj.id]
end
end
end
I originally had it just print first and last name to the CSV. That's what I still get in production.
And here is my deployment pipeline:
$ yarn install --check-files
$ rails db:migrate
$ RAILS_ENV=production rails assets:precompile
$ touch tmp/restart.txt
Running Rails 6.0.2.2, Webpack 4.42.0, and Ruby 2.5.5 on Passenger. Hosted by Dreamhost.
This worked for me and was thanks to max's suggestion in the comments.
I placed a stale? block around the send_data line and when I made an update it showed up instantly.
The new controllers/users_controller.rb looks like this:
def index
#users = User.all
respond_to do |format|
format.csv {
if stale?(#users)
send_data #users.to_csv
end
}
end
end
This block came from here:
https://thoughtbot.com/blog/take-control-of-your-http-caching-in-rails

Imagemagick no such file or directory error in Mac

I'm using carrierwave to upload images from my rails app, and later pass that image to resque for resizing them in the background. The image gets uploaded properly. The problem when resque tries to resize it, mini_magick says that "No such file or directory"
This is my ImageController code which handles the upload
#create image and embed into story
def create
img_attr = params[:image]
img_attr[:media] = params[:image][:media].first if params[:image][:media].class == Array
image = Image.new img_attr
#story.images << image
if #story.save
Resque.enqueue(ImageQueue,image.id)
respond_to do |format|
format.json {
render :json => [image.to_jq_upload].to_json
}
end
else
render :json => [{:error => 'custom_failure'}], :status => 304
end
end
And this is my Resque code
class ImageQueue
#queue = :image_queue
def self.perform(image_id)
image = Image.find image_id
image.recreate_delayed_versions!
image.save
end
end
And the upload path is set here
def store_dir
"uploads/stories/#{model.viewable_id}/res"
end
This is the error stack that I get
No such file or directory - /uploads/stories/533d5b8756617390c0070000/res/636a8fe128.jpg
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/mini_magick-3.7.0/lib/mini_magick/image.rb:110:in `initialize'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/mini_magick-3.7.0/lib/mini_magick/image.rb:110:in `open'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/mini_magick-3.7.0/lib/mini_magick/image.rb:110:in `open'
/Users/skmvasu/repo/mangoweb/app/uploaders/image_uploader.rb:97:in `original_dimensions'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/carrierwave-0.10.0/lib/carrierwave/uploader/processing.rb:84:in `block in process!'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/carrierwave-0.10.0/lib/carrierwave/uploader/processing.rb:76:in `each'
/Users/skmvasu/.rvm/gems/ruby-2.0.0-p451/gems/carrierwave-0.10.0/lib/carrierwave/uploader/processing.rb:76:in `process!'
The weird thing is the same code works in my Linux box, and my production box which also runs Linux, but not on my new Mac. Is it a problem with ImageMagick? I'm installing it through Homebrew. I even tried uninstalling it and reinstalling it with source, but that didn't work either.
I'm not sure what I'm doing wrong here? Please help me solve this issue.
As per the error,
No such file or directory - /uploads/stories/533d5b8756617390c0070000/res/636a8fe128.jpg
Either 636a8fe128.jpg is not there at the given path i.e., /uploads/stories/533d5b8756617390c0070000/res or
/uploads/stories/533d5b8756617390c0070000/res one or all of the directories in this path are not there. I would recommend go to terminal and navigate through the path and see if it allows you to change directory till you reach res directory. If yes, then inside res directory do ls -l and see if the output shows 636a8fe128.jpg file.
UPDATE
Specify the full path including Rails.root:
def store_dir
"#{Rails.root}/public/uploads/stories/#{model.viewable_id}/res"
end
without #{Rails.root}/public/, path generated was /uploads/stories/533d5b8756617390c0070000/res/636a8fe128.jpg where the first / points to the root directory of the server.

Delete a folder after the cucumber scenario

I have 2 cucumber scenarios that simulate paperclip image upload. I want to remove those folders again once scenarios are complete.
I have the following attachment folder structure:
:url => "/system/:attachment/:listing_id/:id/:style_:filename"
Paperclip automatically deletes the :id/:style_:filename folder but not the parent folder.
I have a the following in my listings controller (1 listing has many images) which works great to remove the image folder with the listing id when the listing is deleted. I need to simulate the same in Cucumber after the step is run.
def destroy
#listing = Listing.find(params[:id])
# if destroy was a success, remove the listing image folder
if #listing.destroy
end
require 'fileutils'
dir = Rails.root + '/system/photos/' + #listing.id.to_s()
FileUtils.rm_rf(dir)
respond_to do |format|
format.html { redirect_to(listings_url) }
format.xml { head :ok }
end
end
I could a) tell cucumber to delete the :listing_id folder name after running through the scenario or b) tell cucumber to delete the listing as the final step?
I've tried adding this to my cucumber env.rb file:
AfterStep('#paperclip') do
# This will only run before steps within scenarios tagged
# with #cucumis AND #sativus.
# delete folders that were created with paperclip during the test
require 'fileutils'
##listing.id = 55
#dir = Rails.root + '/system/photos/' + #listing.id.to_s()
dir = Rails.root + '/system/photos/55' # NOT WORKING
FileUtils.rm_rf(dir)
end
But that causes problems because 1) I don't know how to get the #listing.id from that scenario, and 2) even when I hardcode it (as above) it doesn't remove it.
Any thoughts?
Already a bit older, but as I just ran over the same issue myself here is what I did:
dir = Rails.root + 'images/'
dir.rmtree if dir.directory?
# or the short form, if you know the directory will be there
(Rails.root + 'images/').rmtree
So I guess the problem was your '/' at the beginning of the folder. At least for me it didn't work with that slash.
I would leave a comment, but don't have the points (or so I would assume) to do so.
There really is no reason that this shouldn't work. Have you confirmed that FileUtils.rm_rf(dir) does in fact remove the directory in the test environment?
You can test this in 'script/console test'.
You can hook into Cucumber's at_exit to remove any folders you like. I'm using the attached code in features/support/uploads_cleaner.rb.
# Removes uploaded files when all scenarios for the current test process
# are finished. Ready for parallel_tests, too.
require 'fileutils'
at_exit do
directory_name = "#{ Rails.env }#{ ENV['TEST_ENV_NUMBER'] }"
uploads_path = Rails.root.join('public/system', directory_name)
FileUtils.remove_dir(uploads_path) if uploads_path.directory?
end
Reposted from this makandra Card.

Resources