I am upgrading an app from Rails 3.2.11 to 3.2.17 and I'm getting the following error message:
DEPRECATION WARNING: ActiveSupport::Memoizable is deprecated and will be removed in future releases, simply use Ruby memoization pattern instead.
I know what memoization is, and the offending code appears to be the following:
def api
#client.vm_by_name(name) if cluster
end
memoize :api
I'm not quite sure how to memoize this using a ruby memoization pattern. The previous techs have memoized the api method. Anyone got any ideas?
Use this:
def api
#api ||= #client.vm_by_name(name) if cluster
end
Note on thread safety.
Related
Hi I'm trying to get Oauth2 access from quickbooks but I'm getting this warning on command promt from rails server and nothing happens server just keeps loading the same warning;
Here's the line that gives error (located in the gem);
def escape(value)
URI::escape(value.to_s, OAuth::RESERVED_CHARACTERS)
rescue ArgumentError
URI::escape(value.to_s.force_encoding(Encoding::UTF_8), OAuth::RESERVED_CHARACTERS)
end
I looked at other complains about this error and I tried to replace URI::escape() commands with CGI::escape() but then I got this error;
Can anyone tell me how to get rid of this error and find an alternative that works?
My Ruby version: ruby 2.7.2p137
My Rails Version: Rails 6.1.4
Thank you.
If all you need is a working implementation of URI.escape, you could re-implement it yourself:
# config/initializers/uri.rb
module URI
def self.escape(*args)
DEFAULT_PARSER.escape(*args)
end
end
This will effectively remove the warning and delegate the escape call to the default parser, which also works in Ruby 3.
Note that this is just a quick patch to silence the warning. In the long run, you should find a replacement for the outdated gem(s).
I am experimenting with gem development, right now specifically generators. So far I have successfully created two generators that do their job just perfectly. These two generators are in the same directory.
However, right now I have to call each of them separately.
What I'd like to do is just call one generator and have that generator call all the other ones. Just would type
rails g generator_name
and this would call x other generators.
Does anyone know how would I got about doing this?
Help is much appreciated, thanks!
In your generator, you can just call
generate "some:generator" # can be anything listed by 'rails g'
for example:
module MyGem
class InstallGenerator < Rails::Generators::Base
def run_other_generators
generate "jquery:install" # or whatever you want here
end
end
end
By the way, if you are working on Rails 3 gems, this question can also help out:
Rails 3 generators in gem
Another possibility is to use something like
invoke 'active_record:model', 'foo bar:string baz:float'
which is not as clean as generate, but has one advantage: When your generator gets called via rails destroy, this call -- like may other of Thors actions -- will try to revoke the action of the generator you invoke.
There's a catch however: Probably due to Thors dependency management, this only works once per generator you want to call, meaning that a second invoke of the same generator will do nothing. This can be circumvented by using a statement like
Rails::Generators.invoke 'active_record:model', '...', behavior: behavior
instead. In this case you have to explicitly pass through the behavior of your generator (which is a method returning values like :invoke, :revoke and possibly others, depending on which command -- rails generate, rails destroy, rails update, etc. -- called your generator) to achieve the same result as above. If you don't do this, the generator you call with Rails::Generators.invoke will also be executed when running your generator with rails destroy.
Alternatively you could stick to invoke and try to tamper with Thors invocation system. See also here for example.
Generators are based off of Thor, so you can use the apply method.
This is what the Rails Templater gem does. (Here's a walk through the Rails Templater gem.)
Take a look at the scaffold generator that comes with rails.
/Users/XYZ/sources/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb
def manifest
record do |m|
#....rest of the source is removed for brevity....
m.dependency 'model', [name] + #args, :collision => :skip
end
end
Here the scaffold generator is using the model generator. So take a look at the dependency method. You can find the API docs for it over here.
I've been trying to use the code here:
http://snafu.diarrhea.ch/blog/article/4-serving-static-content-with-rails
but I'm getting errors like:
undefined method `template_exists?' for #<StaticController:0xb74cbe4c>
How can I update this method to Rails 2.5? Probably there are other deprecated things too.
The method call template_exists? is deprecated as of Rails 2.2.1 (see: Rails APIdock)
A little bit of digging revealed the solution, by the original author, in the following article article. Basically requires adding the method into the StaticController, derived from ApplicationController and thus gives the method.
I'm trying to port over some of my old rails apps to Ruby 1.9 and I keep getting warnings about how "Ruby 1.9 doesn't support Unicode normalization yet." I've tracked it down to this function, but I'm getting about 20 warning messages per request:
rails-2.3.5/activesupport/lib/active_support/inflector.rb
def transliterate(string)
warn "Ruby 1.9 doesn't support Unicode normalization yet"
string.dup
end
Any ideas how I should start tracking these down and resolving it?
If you are aware of the consequences, i.e. accented characters will not be transliterated in Ruby 1.9.1 + Rails 2.3.x, place this in config/initializers to silence the warning:
# http://stackoverflow.com/questions/2135247/ruby-1-9-doesnt-support-unicode-normalization-yet
module ActiveSupport
module Inflector
# Calling String#parameterize prints a warning under Ruby 1.9,
# even if the data in the string doesn't need transliterating.
if Rails.version =~ /^2\.3/
undef_method :transliterate
def transliterate(string)
string.dup
end
end
end
end
Rails 3 does indeed solve this issue, so a more future-proof solution would be to migrate towards that.
The StringEx Gem seems to work pretty well. It has no dependency on Iconv either.
It adds some methods to the String class, like "to_ascii" which does beautiful transliteration out of the box:
require 'stringex'
"äöüÄÖÜßë".to_ascii #=> "aouAOUsse"
Also, the Babosa Gem does a great job transliterating UTF-8 strings, even with language support:
"Jürgen Müller".to_slug.transliterate.to_s #=> "Jurgen Muller"
"Jürgen Müller".to_slug.transliterate(:german).to_s #=> "Juergen Mueller"
Enjoy.
That method definition is wrapped in an if-statement for Ruby 1.9. Right above it, you will find the regular definition, which shows a bit more of what this is doing. It's a method used to convert accented characters into their regular variants. E.g.: á => a, or ë => e
But this method is only used in parameterize, which is in turn defined right above transliterate. This is all still in ActiveSupport. I can't find anything that is directly calling parameterize.
So perhaps you're using parameterize or transliterate yourself, somewhere in your Rails application?
Common usage (according to the parameterize documentation) is for creating friendly permalinks from arbitrary strings, much like SO does, for example:
http://stackoverflow.com/questions/2135247/ruby-1-9-doesnt-support-unicode-normalization-yet
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Replace the body of the method with
raise "transliterate called"
and observe a backtrace which will show you where the stuff is coming from at the first call. Your app will of course collapse as well but that will likely give you the culprit from the first try.
I appreciate that this is a dirty way to solve the problem, but having read the error message I'm aware of the issue. So I want to get rid of the warnings. I dropped this code in environment.rb:
module ActiveSupport
module Inflector
# Calling String#parameterize prints a warning under Ruby 1.9,
# even if the data in the string doesn't need transliterating.
# Maybe Rails 3 will have fixed it...?
if RAILS_GEM_VERSION =~ /^2\.3/
undef_method :transliterate
def transliterate(string)
string.dup
end
end
end
end
If you'd rather not monkey patch the Inflector module, you can also do this...
Both of the following worked for me to silence this annoying "Ruby 1.9 doesn't support Unicode normalization yet" warning:
silence_stream(STDERR) {
whatever_code_caused_transliterate_to_be_called
}
or
silence_warnings {
whatever_code_caused_transliterate_to_be_called
}
This does have the disadvantage that it requires cluttering up your calling code, but it is a technique you can use generally whenever you don't want to see warnings or other output.
activesupport provides silence_stream and silence_warnings in activesupport-2.3.11/lib/active_support/core_ext/kernel/reporting.rb
String#unicode_normalize, String#unicode_normalize!, String#unicode_normalized? will be introduced in Ruby 2.2. Sample code and implementation can be seen in test case, lib/unicode_normalize.rb and lib/unicode_normalize/normalize.rb.
// U+00E1: LATIN SMALL LETTER A WITH ACUTE
// U+U+0301: COMBINING ACUTE ACCENT
puts "\u00E1" == "a\u0301".unicode_normalize(:nfc)
puts true == "a".unicode_normalized?(:nfc)
In Rail 2.3.2 can I have merb style action definitions:
Eg: instead of
def show
#user = User.find(params[:id])
end
Can I have:
def show(id)
#user = User.find(id)
end
What kind of crazy monkey patching do I need to do to get this working, note I only need this working for MRI so ParseTree is an option.
Note: there is a Rails 3 port of this functionality now.
You could change all params in to instance var's (eg. #id) in a before_filter...
EDIT: I was wrong: Method#parameters has been added to Ruby 1.9.2.
Original:
No, this is not possible in Rails.
There is almost zero chance of this making it into Rails 3.0. merb-action-args used ParseTree which doesn't and will not work on Ruby 1.9, therefore making it unlikely that it will be included in Rails.
I am running Rails 2.3.3 and User.find(id) works just fine.