Where did my filename extension go in the parameter list - ruby-on-rails-3

I am following this answer while trying to figure out how to display images located in my app directory Rails 3, displaying jpg images from the local file system above RAILS_ROOT
I've created a controller as shown there, added the match line to routes.rb, and in a test webpage I want to load up an image called test.jpg using the code
<img src="/serve_image/test.jpg" />
But I get an error saying the file <...>/public/images/test was not found.
Then I went and renamed my image so that the .jpg was gone, and then the script found my image and loaded it up as wanted.
Any ideas where the extension went? I am not sure how to debug this issue.

By default, Rails doesn't match dots in a dynamic segment. So for this route:
match '/serve_image/:filename' => 'images#serve'
:filename will only match up to the first dot it finds. So /serve_image/test.jpg will match test as the filename and will think you're expecting a JPG as a response. What you need to do is tell the router that you want to include the dot in the filename, something like this:
match '/serve_image/:filename' => 'images#serve', :constraints => {:filename => /[^\/]+/}
That will match anything except a forward slash, giving you your complete filename in params[:filename]
See the Rails Routing guide section on Dynamic Segments for more info.

Related

Ionic4 cordova-plugin-mobile-ocr how to set correct path of static file

when I follow https://ionicframework.com/docs/native/ocr to integrate ocr feature, I cann't set correct path to my static image which is at /src/assets/imgs/test.png:
this.ocr.recText(OCRSourceType.NORMFILEURL, "file://path/to/image.png" /*<-this parameter*/)
.then((res: OCRResult) => console.log(JSON.stringify(res)))
.catch((error: any) => console.error(error));
I tried different combinations:
/assets/imgs/test.png
/assets/imgs/test.png
file://assets/imgs/test.png
file:///assets/imgs/test.png
...
this have frustrated me for a couple days, please help, thanks,
the first step you have to create a folder inside the assets folder (lets say its name is images) and put your image inside it.
then write this path in your code "assets/images/yourImage.png"

When I go to root uri my images work, but when I go to base.com/controller/action uri they are broken images

I've got a simple app that shows images when I go to the root uri which points to page#index. Pictures work just fine this way, but when I go to /page/index the pictures are broken. What causes this?
routes.rb
root :to => "page#index"
match ':controller(/:action(/:id))(.:format)'
When I view source and try to click on the images from /page/index I get:
Unknown action
The action 'assets' could not be found for PageController
Even if I put
match ':controller(/:action(/:id))(.:format)'
before
root :to => "page#index"
it still doesn't render the images.
edit: since I'm getting a controller error. Here is my page_controller.rb
class PageController < ApplicationController
def index
render "index"
end
end
Aha. That <img> tag should look like this instead:
<img id="email" src="/assets/email.png" alt="Contact" />
Note the forward slash at the beginning of the src attribute. With the slash, the browser will always try to pull the image from:
http://my.web.site/assets/email.png
But without it, you get a relative path, so the browser will try to get:
http://my.web.site/the/current/page/assets/email.png
Which doesn't exist. Unless your current page is the root URL, which is why it works in that one circumstance.
Hope that helps!

Rails route to catch everything except assets

I'm trying to allow admin to create pages on the root path. So far i have:
get ':path' => "pages#show" ,:as =>:page, :path => /[^\.]+/
Basically i'm trying to ignore all paths with a dot in them (like .png). This does not seem to work as everything is rejected (i only want things in the public directory to be rejected, like fonts, icons, images..)
Thanks
As I explained in my comment above, "everything in public is directly rendered by the webserver" is NOT true if the desired asset does not exist. This will result in your catch-all route catching this undesired side-effect. This could cause a number of problems, as I explained. So, A specific catch-all route is needed to compensate for this:
get ':path' => "pages#show", :as => :page, :constraints => lambda{|req| req.path !~ /\.(png|jpg|js|css)$/ }
you can manipulate the regex how ever you see fit as my goal was just to get you on the right track by showing you that you can pass a block to the :constraints option. Also, I didn't just test req.format because that would exclude requests with header information for js format and would result in the catch all not working for these types of requests (not a usual case for a catch-all, but that's irrelevant). By using req.path instead, the header info is left intact/working and the path dictates whether or not this request is caught by this route.
I hope this helps you.
TESTING:
To test to see if your catch-all is actually catching what you want and not additional public resources, follow these steps. First put a debugger in your catch-all action, in your PagesController. Then make a request to a public file png/js/css file that DOES exist, like localhost:3000/images/example_image.png, and it should not hit your catch-all, as usual. Now, change the path to an image that doesn't exist, localhost:3000/images/no_image.png . If the request does not hit your debugger, your catch-all is not catching the image file request, and your ALL SET. If the request does hit your debugger, that means your catch-all is catching the image file request which means you need to revise your constraints in your catch-all.
By default dynamic segments don’t accept dots – this is because the
dot is used as a separator for formatted routes. If you need to use a
dot within a dynamic segment add a constraint which overrides this –
for example :id => /[^/]+/ allows anything except a slash.
http://guides.rubyonrails.org/routing.html#bound-parameters
So just removing the condition works. There might be another better solution to this problem though.

Paperclip not saving attachment

I am unable to get Paperclip to save my attachment. Rather than saving a single image (such as an avatar as seems to be the common usage), I need to be able to upload/save multiple files; therefore I have a User model and an Asset model. The file information gets properly stored in the asset table, but the attachment itself is not saved in the filesystem as expected.
My log shows the message:
"[paperclip] Saving attachments."
but the attachment is not saved.
Here's a gist with the details: https://gist.github.com/1717415
It's gotta be something simple that I'm missing...
OK... found the problem and it's now working.
The first issue was my naming of the columns in the asset model. I had used simple names: i.e., :description, :file_name, :file_size, :content_type. What I needed to use was: :upload_description, :upload_file_name, :upload_file_size, :upload_content_type where the 'upload' (or whatever you want to use) is a prefix that Paperclip will recognize.And of course that changed my Asset model to reference :upload not :asset, as in:
has_attached_file :upload
Secondly (and this post Adding :multipart => true throws Undefined Method "name" error was key to understanding this) was that you cannot specify the full column name (:upload_file_name) in your view, just specify the prefix and Paperclip magically understands what you want.
Hope this helps someone else!
Did you install ImageMagick?
Did you added image_magick command_path via initializer?
if not, checkout this answer:
Weird paperclip error message

Trying to place avatar on every page in PHPbb Forum. Only showing up in index page... any ideas?

The website that im trying to make it work on is http://www.phone7forum.com/
The way I get it to show up on the index page is adding this code to the core index.php page right below this:
// Assign index specific vars
'S_AVATAR' => get_user_avatar(
$user->data['user_avatar'],
$user->data['user_avatar_type'],
$user->data['user_avatar_width'],
$user->data['user_avatar_height']
),
Then I can use {S_AVATAR} in my template but it ONLY shows up in the index file... So another phpbb guy suggested that I take that same code from above and place it in the includes/functions.php file right below this:
// The following assigns all _common_ variables that may be used at any point in a template.
I did that, and though it seemed to "try" and work I clicked on a few pages outside the index page and got a fatal error message:
Fatal error: Call to undefined function get_user_avatar() in /home/content/04/6534704/html/phone7forum/includes/functions.php on line 4385
Does anyone have any ideas?
IIRC get_user_avatar() is a function from functions_display. If you want to use it in the functions file, you have to include it.
Put it into an if condition to have it only load if you're on a page where function_display isn't already included:
if(!function_exists('get_user_avatar')){ include_once($phpbb_root_path . 'includes/functions_display.' . $phpEx); }