With Rails 6.0, the to_spreadsheet gem raises the following error:
Invalid formats: "xlsx", "html"
…/gems/actionview-6.0.0/lib/action_view/lookup_context.rb:288:in `formats='
This gem aside, it seems that ActionViews lookup_context.rb now raises an ArgumentError when formats other then a few basic ones ([:html, :text, :js, :css, :xml, :json]) defined in ActionViews Template types.rb are used.
I tried to extend the basic types like so:
ActionView::Template::Types.symbols.concat([:xlsx, 'xlsx', 'html'])
Although this did indeed add to the ActionView::Template::Types, Rails still raises the ArgumentError described above.
So can these types actually be extended the way I did? Or am I on the completely wrong track to mitigate this error?
Note: MIME-Type for .xlsx is registered by the gem, thats why it worked with Rails versions < 6.
To register a new MIME type, you should add it to config/initializers/mime_types.rb...which should have a commented example of how to add a MIME type (# Mime::Type.register "text/richtext", :rtf).
I would consider not using the to_spreadsheet gem. The last commit was 9 months ago. This may not mean it doesn't work...but I would be skeptical.
Related
I am running Rails 5.0.7.2. In my project I have so far always set the mime type like follows:
render :js => File.read(js_file), :content_type => 'application/javascript'
(for example). It appears, however, I shouldn't be doing it this way but by using the Class MIME::Type. On Rails console I can find it and print its methods. I used (MIME::Type.methods - Object.methods).sort. It only gives me three methods: match, simplified and i18n_key. The documentation says there should be methods lookup and lookup_by_extension.
When I try using MIME::Type.lookup('application/javascript') in my code I get the same error: as if the method wasn't defined.
Does anybody know what is the problem? Thanks in advance!
Maxence's comment solved the problem. Typing Mime::Type instead of MIME::Type is all it took. I should have been more careful when reading the docs. Bit awkward that MIME::Type gave me a result other than nil, or else I would have found my error long ago.
I am trying to create a rails app that will upload Anki decks (apkg file extension) using paperclip. The error I am getting states:
"File has an extension that does not match its contents."
I am wondering what is the correct way to file map this extension. Thanks.
Well, you're running into Paperclip's file type validations. There's apparently a bunch of different things that can trigger this message. If, for instance, you're running on Windows, you have to manually install the file utility. As of version 4.0.0, every upload model needs to have a filetype validation of some sort, and has an un-removable validation to protect against filetype spoofing.
I don't actually know which of these you're running into, but that same link suggests solutions to each.
If you don't have any kind of filetype validation, you probably need to add some:
validates_attachment_file_name :column_name, :matches => [/apkg\Z/]
or, if not feeling security-conscious:
do_not_validate_attachment_file_type :column_name
For the second, well, I'm just going to quote the docs:
[The unavoidable spoofing check] can sometimes cause false validation errors in applications that
use custom file extensions. In these cases you may wish to add your
custom extension to the list of file extensions allowed for your mime
type configured by the mime-types gem:
# Allow ".foo" as an extension for files with the mime type "text/plain".
text_plain = MIME::Types["text/plain"].first
text_plain.extensions << "foo"
MIME::Types.index_extensions text_plain
This question already has answers here:
Paperclip exception : Paperclip::AdapterRegistry::NoHandlerError
(11 answers)
Closed 8 years ago.
I'm a n00b to the paperclip gem, so please excuse me, but I have spent the better part of two hours on this without progress (and I have watched the railscast on it):
My Rails app has a model with a paperclip attachment:
class Foo::Bar < ActiveRecord::Base
attr_protected :id
has_attached_file :mydocument
end
And whenever I try to submit a form with a blank file field for this attachment I get the following error:
Paperclip::AdapterRegistry::NoHandlerError: No handler found for ""
What am I to do? (I installed ImageMagick and specified Paperclip.options[:command_path] = 'C:\Program Files\ImageMagick-6.8.4-Q16' in my environment file, not that I think that should make a difference in this case.)
I've uninstalled and reinstalled paperclip. I've restarted my computer. I ran the app on a co-worker's computer, and didn't get the error. But on my machine, I still get the error.
After reading through the Paperclip source, it looks like you are running into an error in the call trace:
Foo::Bar.mydocument = document
# calls
Foo::Bar.attachment_for(:mydocument).assign(document)
# calls
file = Paperclip.io_adapters.for(document)
# calls
handler_for(document).new(document)
And it looks like the handler_for call is failing because target is an empty string or is empty-string-like.
In your controller, try printing the params object to see what is in params[:foo_bar][:mydocument]. That may lead you closer to the root issue. Things that may be the problem could include
Different attribute names between controller and view
Different attribute names between controller and model
A messed up form_tag or form_for that doesn't have the correct encoding set (try :html => {:multipart => true}).
Starting with Rails 3.0, from time to time, I've been receiving an exception notification like this:
ActionView::MissingTemplate: Missing template [...] with {:locale=>[:en],
:formats=>[:text], :handlers=>[:erb, :builder, :haml]}. Searched in: * [...]
For instance, an arbitrary hand-written URL like http://example.com/some/path/robots.txt raises the error. Not fun.
I reported the problem in this ticket quite a long ago, and been using the patch mentioned here, but the problem persists.
https://rails.lighthouseapp.com/projects/8994/tickets/6022-content-negotiation-fails-for-some-headers-regression
A fix is suggested in this blog post,
http://trevorturk.wordpress.com/2011/12/09/handling-actionviewmissingtemplate-exceptions/
To use this:
respond_to do |format|
format.js
end
But it doesn't feel right to me, as I'm not interested in overloading an action with multiple formats. In my app, there are separate URLs for HTML and JSON API, so simple render should be sufficient.
Should I just swallow the exception by rescue_from ActionView::MissingTemplate and return 406 myself?
Is there a better way to handle this situation?
Or I can ask this way - in the first place, is there any real-world usefulness in raising this kind of exception on production?
If you've no need for formatted routes you can disable them with :format => false in your route specification, e.g.
get '/products' => 'products#index', :format => false
This will generate a RoutingError which gets converted to a 404 Not Found. Alternatively you can restrict it to a number of predefined formats:
get '/products' => 'products#index', :format => /(?:|html|json)/
If you want a formatted url but want it restricted to a single format then you can do this:
get '/products.json' => 'products#index', :format => false, :defaults => { :format => 'json' }
There are a number of valid reasons to raise this error in production - a missing file from a deploy for example or perhaps you'd want notification of someone trying to hack your application's urls.
Best that worked for me is in application_controller.rb:
rescue_from ActionView::MissingTemplate, with: :not_found
After some source diving I found another way. Put this in an initializer.
ActionDispatch::ExceptionWrapper.rescue_responses.merge! 'ActionView::MissingTemplate' => :not_found
If you have a resource that will only ever be served in one format and you want to ignore any Accept header and simply force it to always output the default format you can remove the format from the template filename. So for instance, if you have:
app/views/some/path/robots.txt.erb
You can change it to simply
app/views/some/path/robots.erb
Some schools of thought would say this is a bad thing since you are returning data in a different format from what was requested, however in practice there are a lot of misbehaving user agents, not every site carefully filters content type requests, and consistently returning the same thing is predictable behavior, so I think this is a reasonable way to go.
Try adding
render nothing: true
at the end of your method.
If there are specific paths that periodically get called that generate errors -- and they are the same set of urls that get called regularly (i.e., robots.txt or whatever) -- the best thing to do if you can is to eliminate them from hitting your rails server to begin with.
How to do this depends on your server stack. One way to do it is to block this in directly in RACK prior to having the url passed into rails.
Another way may be to block it in NGINX or Unicorn, depending on which web listener you're using for your app.
I'd recommend looking into this and then coming back and posting an additional question here on 'How to Block URL's using Rack?" (Or unicorn or nginx or wherever you think it makes sense to block access.
I would like to use I18n.t in an initializer file in Rails 3.1.1.
This question already exists for Rails 2 (http://stackoverflow.com/questions/3514536/unable-to-use-i18n-t-call-in-an-initializer-file). Supposedly, it was answered by a subsequent release. It appears to be an issue again in Rails 3.1.1.
The problem:
I have a custom time format called :dxl.
I would like to format my Email.sent_at datetime as :dxl.
The solution:
In can add the format to en.yml (time.formats.dxl) and use it with:
I18n.localize(email.sent_at, :format => :dxl)
I also want to show the utc time. I do not see a way to use I18n for this, so I am using:
email.sent_at.utc.to_s(:dxl)
The rub:
To support to_s(format), I believe I need to assign Time::DATE_FORMATS[:dxl] in an initializer (e.g. config/initializers/time_formats.rb).
I would rather not duplicate the strftime format string in both en.yml and the initializer.
Unfortunately, it looks like I18n is not usable within an initializer. When I add this to config/initializers/time_formats.rb:
Time::DATE_FORMATS[:dxl] = I18n.translate('time.formats.dxl')
I get:
> Time.now.utc.to_s(:dxl)
=> "translation missing: en.time.formats.dxl"
Is there a way to ensure I18n is ready (has read the en.yml file) in an initializer?
I did verify that the translation does work correctly if I copy/paste the strftime format into the initializer.
Thanks.