Rails equivalent for MapPath (from ASP.NET) - ruby-on-rails

Does Rails have an equivalent of the Server.MapPath method from ASP.NET? I've tried looking for one, but couldn't find anything.
Edit: I need this to generate a PDF with some images stored on the server. I know the relative path (URL) of the images, but I need an absolute path on disk to load them. I use FPDF for this and even though it says it accepts an URL, it doesn't seem to be the case (or I couldn't make it work).
It checked that it works with a hardcoded physical disk path and now I need to make it flexible.

Ruby has one: File.expand_path.
You can also use Rails.root to get the current path to rails project, then compose the path from there.
File.join(Rails.root, "public", "404.html")
File.expand_path("public/404.html", Rails.root)

Related

Rails, active storage, attach_one photo, doesn't work when fetching photo from folder

So I am trying to attach a picture to an instance of my database, but I can't find the correct path syntax to fetch it from my images folder. What am I doing wrong?
It works fine when I host an image on my server with this syntax:
bar1.photo.attach(io: URI.open("https://www.ogsoundfx.com/ogcoding/photo_test/image1.jpg"), filename: 'bar1')
But this doesn't work:
bar1.photo.attach(io: File.open('../../app/assets/images/bar1.jpg'), filename: 'bar1')
Here is a capture of the seed.rg file from where I am running this code:
Is my path wrong? To be honest I tried every possible way I could think of, but never made it work.
Thanks!
Probably what you want is Rails.root. As you can see in this api documentation this method returns a Pathname object which handles paths starting with a / as absolute (starting from the root of the filesystem).
bar1.photo.attach(io: File.open(File.join(Rails.root,'app/assets/images/bar1.jpg')), filename: 'bar1')
This should solve your question.
It seems there is an issue with the file path.
The current directory on your code is the app root directory and .. in the path represents its parent directory.
Consider your rails app resides under parent_1/parent_2/parent_3/rails-mister-cocktail, then the path you have used will search for the attachment under parent_1/rails-mister-cocktail/app/assets/images/bar1.jpg
Please find the below output from irb for better understanding:
2.6.3 :002 > File.expand_path('../../app/assets/images/logo.png')
=> "/Users/mac1/Documents/RubyProjects/app/assets/images/logo.png"
2.6.3 :003 > File.expand_path('app/assets/images/logo.png')
=> "/Users/mac1/Documents/RubyProjects/LiveProject/testapp/app/assets/images/logo.png"
Try the below:
bar1.photo.attach(io: File.open('app/assets/images/bar1.jpg'), filename: 'bar1')
You can also read the files relative to the root directory of your rails app.
File.open(File.join(Rails.root, %w(app assets images bar1.jpg)))

Where does active storage store files (on disk), and how can I retrieve them physically?

I am using active storage with Rails 5.2. I am following the EdgeRails guide, and have configured Active-Storage to use the local disk.
The file uploads work great when I am using the Rails App.
However, the problem is that I need to physically access those uploaded files without using Rails as a mediator.
A query for where the files are stored returns this:
url_for(#employee_staff.avatar)
=> "/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBGUT09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--e76664d247cb5437fe1cd11f7ee0ded24f95aee2/profilepic3.jpeg"
I am trying to figure out where this file path is saved in my local disk. So far, I've had no luck.
Any explanations about how Active-Storage works and where I can see the uploaded files are greatly appreciated.
On your local development machine (since you mentioned local disk), you should have a file config/storage.yml that has a block similar to below:
local:
service: Disk
root: <%= Rails.root.join('storage') %>
In this example above, I'm storing the files in a folder named storage in the root of my rails application. Inside that folder you'll find nested folders that aren't meant to be navigated via file explorer/Finder (but you can).
Thru your rails app, via views for example, you'd use the url helpers which aren't well documented yet.
From a rails console, you can try, for a model named Foo, with a has_one_attached :photo
Foo.last.photo.blob.key
It should give you a ~24 character string.
The first 2 characters are a subfolder inside the folder I pointed you to above
The next 2 characters are a subfolder inside that
Inside the subfolder is a file with the name that matches the key you printed out above (no extension). That's your file.
If you have variants:
variant = #employee_staff
.avatar
.attachment
.variant(resize: '100x100')
.processed # If variant is not processed
variant.service.send(:path_for, variant.key) # Absolute path to variant file
ActiveStorage::Blob.service.path_for(#employee_staff.avatar.key)
As seen in this Answer

Generate URL of resources that are handled by Grails AssetPipeline

I need to access a local JSON file. Since Grails 2.4 implements the AssetPipeline plugin by default, I saved my local JSON file at:
/grails-app/assets/javascript/vendor/me/json/local.json
Now what I need is to generate a URL to this JSON file, to be used as a function parameter on my JavaScript's $.getJSON() . I've tried using:
var URL.local = ""${ raw(asset.assetPath(src: "local.json")) }";
but it generates an invalid link:
console.log(URL.local);
// prints /project/assets/local.json
// instead of /project/assets/vendor/me/json/local.json
I also encountered the same scenario with images that are handled by AssetPipeline1.9.9— that are supposed to be inserted dynamically on the page. How can I generate the URL pointing this resource? I know, I can always provide a static String for the URL, but it seems there would be a more proper solution.
EDIT
I was asked if I could move the local JSON file directly under the assets/javascript root directory instead of placing it under a subdirectory to for an easier solution. I prefer not to, for organization purposes.
Have you tried asset.assetPath(src: "/me/json/local.json")
The assets plugin looks in all of the immediate children of assets/. Your local.json file would need to be placed in /project/assets/foo/ for your current code to pick it up.
Check out the relevant documentation here which contains an example.
The first level deep within the assets folder is simply used for organization purposes and can contain folders of any name you wish. File types also don't need to be in any specific folder. These folders are omitted from the URL mappings and relative path calculations.

rename file name with eloquent way

File.rename(blog_path + '/' + project_path, File.expand_path(topic_name, blog_path))
I use these code to rename ruby file name, but I think there is a better way to write this functionality with less code since it includes blog_path two times.
The code is OK, but I think there is no need to expand_path here - this method creates an absolute path from the the relative one.
Also, it is good to use File.join to create a path instead just concatenate it with slash - it will be completely OS independent. So I would write your code like this:
File.rename(File.join(blog_path, project_path), File.join(blog_path, topic_name))
Or if you want to get rid of doubled blog_path, change working directory before doing a rename:
Dir.chdir(blog_path)
File.rename(project_path, topic_name)
More info on working with files and directories in Ruby you can find in the article: Ruby for Admins: Files and Directories.

Use user-defined asset servers in Rails

I'm building an application in Rails where sets of images can be created, i.e. the user uploads a file of image names and specifies a path where those images can be found on the web.
So, for example, the image file contains:
image1.jpg
image2.jpg
and the path is specified as http://www.user1-server.com/.
Another user could load his own file of image names, but specify another server: http://www.user2-server.com/ or even http://my-fancy-server.com.
Is there any way to use the AssetTagHelper functionality of Rails to help me generate the image tags?
So, if I'm in the context of user 1, e.g. /users/1/images/1, and use:
image_tag("1.jpg")
it should deliver http://www.user1-server.com/images/1.jpg, but for /users/2/images/1 it should return http://www.user2-server.com/images/1.jpg or http://my-fancy-server.com/images/1.jpg.
I don't think you can change asset host in Rails on the fly like that. Rails is smart enough to not set or override the host passed into an image tag, though. Maybe just write a helper method or something to pass the correct host in?

Resources