Why is YAML.safe_load failing on a YAML alias? - ruby-on-rails

I've a locale file in my Rails application that works fine with Rails, but when I tried to use it with react_on_rails rake task (rake react_on_rails:locale) I'm getting this error:
Psych::BadAlias: Unknown alias: item_attributes
I found that the rake task is basically calling YAML.safe_load, so I prepared the simplest example without Rails and the error is still there. Here's the sample Ruby script:
require 'yaml'
YAML.safe_load(File.open('test.yml'))
And here's the test.yml file (shorter version of the actual locale file):
pl:
language: Polski
dictionary_name: simple
activerecord:
attributes:
line_item: &item_attributes
variant: Produkt
quantity: Ilosc
price: Cena Netto
total_price: Wartosc Netto
vat_rate: VAT
total_vat_amount: Kwota VAT
total_gross_price: Wartosc Brutto
order_item:
<<: *item_attributes
I'm still getting the error:
/usr/local/Cellar/ruby/2.3.1/lib/ruby/2.3.0/psych/visitors/to_ruby.rb:402:in `visit_Psych_Nodes_Alias': Unknown alias: item_attributes (Psych::BadAlias)
Any ideas why this works fine with Rails but fails here? Any other way to avoid duplication in the YAML file and make it work for both Rails and YAML.safe_load?

I found an answer in the Psych documentation, at https://ruby-doc.org/stdlib-2.1.0/libdoc/psych/rdoc/Psych.html.
Aliases can be explicitly allowed by changing the aliases parameter. For example:
x = []
x << x
yaml = Psych.dump x
Psych.safe_load yaml # => raises an exception
Psych.safe_load yaml, [], [], true # => loads the aliases
Whether to allow aliases or not is a boolean passed to safe_load as the fourth argument.

Related

Prettier for YAML - SyntaxError: Nested mappings are not allowed in compact mappings

In my project there is a YAML file for NewRelic newrelic.yml that has a line with Ruby code for setting app_name. The existing config is working, and I need to edit the file, but when I try to do a yarn commit it fail with the following error, that to me looks like a Prettier error.
I have tried to add #prettier-ignore before the line, but it still causes the commit to fail.
node_modules/prettier/index.js:13588
throw error;
^
SyntaxError: Nested mappings are not allowed in compact mappings (18:13)
17 | # Relic. For more details, see https://docs.newrelic.com/docs/apm/new-relic-apm/maintenance/renaming-applications
> 18 | app_name: <%= ENV["SERVER_ENV"] == 'staging' ? 'MyApp (Staging)' : 'MyApp' %>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
My code editor is VSCode incase that is relevant.
So I'd like to either figure out why the # prettier-ignore is not working as the prettier docs indicate it should. Or figure out how to get things formatted to pass, which is the preferred option obviously.
Seems like Prettier doesn't handle ERB in YAML files.
I would add all common configurations into one block and would then re-use that block with YAML aliases.
common: &default_settings
license_key: 1234
log_lever: info
# ...
production:
<<: *default_settings
app_name: MyApp
staging:
<<: *default_settings
app_name: MyApp (Staging)

Disable rest-client output on minitest

I've searched for this, but without success.
I have some tests (minitest) that use RestClient and Webmock. When passing for those tests I always have the request logged, polluting the test ouput:
[$] rake
Run options: --seed 60435
Running:
.........................................................RestClient.get "http://example.com/some_controller/some_action?userLocale=fr_FR", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client/2.0.0 (darwin14.1.0 x86_64) ruby/2.2.1p85" # => 200 OK | 4 bytes
Is there a way to disable this ?
[EDIT]
Just to add, if I call the same address using ruby URL I have nothing logged (even using webmock) so it really is something related with Rest-client.
I already tried to set the ENV['RESTCLIENT_LOG'] variable, but without success.
What about:
RestClient.stub :log, '' do
# Your test code here
end
http://www.rubydoc.info/gems/minitest/4.2.0/Object:stub
You have many other options to redirect the log output:
In your test_helper.rb:
RestClient.log = 'tmp/test.log'
http://www.rubydoc.info/gems/rest-client/1.8.0/RestClient.log=
From the command line:
RESTCLIENT_LOG=tmp/restclient.log bundle exec rails test
In last resort you could monkey patch:
# test_helper.rb
RestClient.class_eval do
def self.log
''
end
end

Setting Environment Variables in Rails 3 (Devise + Omniauth)

I've been trying to figure out how Ryan Bates, in his Facebook Authentication screencast, is setting the following "FACEBOOK_APP_ID" and "FACEBOOK_SECRET" environment variables.
provider :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_SECRET']
There are similar-ish questions around, but no answers that I've been able to get to work on Rails 3.2.1.
UPDATE:
As of May 2013, my preferred way to handle ENV variables is via the Figaro gem
You could take a look at the comments:
You can either set environment variables directly on the shell where you are starting your server:
FACEBOOK_APP_ID=12345 FACEBOOK_SECRET=abcdef rails server
Or (rather hacky), you could set them in your config/environments/development.rb:
ENV['FACEBOOK_APP_ID'] = "12345";
ENV['FACEBOOK_SECRET'] = "abcdef";
An alternative way
However I would do neither. I would create a config file (say config/facebook.yml) which holds the corresponding values for every environment. And then load this as a constant in an initializer:
config/facebook.yml
development:
app_id: 12345
secret: abcdef
test:
app_id: 12345
secret: abcdef
production:
app_id: 23456
secret: bcdefg
config/initializers/facebook.rb
FACEBOOK_CONFIG = YAML.load_file("#{::Rails.root}/config/facebook.yml")[::Rails.env]
Then replace ENV['FACEBOOK_APP_ID'] in your code by FACEBOOK_CONFIG['app_id'] and ENV['FACEBOOK_SECRET'] by FACEBOOK_CONFIG['secret'].
There are several options:
Set the environment variables from the command line:
export FACEBOOK_APP_ID=your_app_id
export FACEBOOK_SECRET=your_secret
You can put the above lines in your ~/.bashrc
Set the environment variables when running rails s:
FACEBOOK_APP_ID=your_app_id FACEBOOK_SECRET=your_secret rails s
Create a .env file with:
FACEBOOK_APP_ID=your_app_id
FACEBOOK_SECRET=your_secret
and use either Foreman (starting your app with foreman start) or the dotenv gem.
Here's another idea. Define the keys and values in provider.yml file, as suggested above. Then put this in your environment.rb (before the call to Application.initialize!):
YAML.load_file("#{::Rails.root}/config/provider.yml")[::Rails.env].each {|k,v| ENV[k] = v }
Then these environment variables can be referenced in the omniauth initializer without any ordering dependency among intializers.

Texticle fuzzy search not finding anything in Ruby on Rails

I've added the following to my gemfile:
gem 'texticle', "2.0", :require => 'texticle/rails' # search gem
I then ran bundle install and bundle installed the gem
I'm using Rails 3.1.0 and I have am using a Postgres database.
I verify that I actually have the string I am looking for in the database table:
ruby-1.9.2-p290 :004 > Hotel.first
Hotel Load (0.4ms) SELECT "hotels".* FROM "hotels" LIMIT 1
=> #<Hotel id: 1, title: "Marriot Hotel", created_at: "2012-03-01 23:53:16", updated_at: "2012-03-01 23:53:16">
When I run `Hotel.search('e')
ruby-1.9.2-p290 :005 > Hotel.search(:title => 'e')
Hotel Load (1.4ms) SELECT "hotels".*, ts_rank(to_tsvector("hotels"."title"), to_tsquery('e')) AS "rank0.4785527956789428" FROM "hotels" WHERE (to_tsvector('english', "title") ## to_tsquery('e')) ORDER BY "rank0.4785527956789428" DESC
=> []
I get nothing. I tried running Hotel.search('e') and still nothing. If I try Hotel.search(:title => 'Marriot') then it works but the reason I am using Texticle is for the fuzzy search.
Am I missing any other configurations?
Thanks
There are a couple things I would suggest checking:
Verify an extension has been created manually for each database involved. I didn't have luck with 'texticle:install_trigram'. And if you're using Heroku, there may be additional steps, especially if you haven't migrated from your shared database.
Use the fuzzy_search method. In the latest version of Texticle, there are actually 3 new methods; the original #search method has been deprecated.
To manually install the extension:
Local Dev/Test
psql -U <username>
\l
\c db_development
CREATE EXTENSION pg_trgm;
\dx
\c db_test
CREATE EXTENSION pg_trgm;
\dx
\q
Heroku Integration/Production
heroku pg:psql
\dx
CREATE EXTENSION pg_trgm;
\dx
More?
PostgreSQL Trigrams (fuzzy search)
What's new in PostgreSQL 9.1 - PostgreSQL wiki
trigram | Tumblr
Installing PostgreSQL Trigram
Install Trigram Rake Task by benhamill · Pull Request #63 · tenderlove/texticle · GitHub
texticle:install_trigram - on Heroku? · Issue #15 · tenderlove/texticle · GitHub
New Texticle search methods (source code)
texticle/lib/texticle.rb at master · texticle/texticle · GitHub
My understanding of the way Texticle works is that it's going to do full text search on your string columns but not necessarily do fuzzy search by default. If you look at the query that it's generating in Postgres, it's looking for a match on 'e' rather than any word that contains the letter 'e'.
You can read the Postgres docs here:
http://www.postgresql.org/docs/9.1/static/datatype-textsearch.html
That said, I see support for prefix matching but not postfix in the docs, although I might be missing something.
What happens if you do Hotel.search('Marr:*') ?

Rails character encoding different between rake & console

I have a rake task that pulls some data from a MS SQL db, and recently I noticed that some special characters get encoded as a question mark '?'. While trying to dig into this issue, I realized that I could only repo it as a rake task, but not from the console.
Here is a snippet of what the code looks like:
require 'dbi'
namespace :db do
task :test => :environment do
db2 = DBI.connect("DBI:ODBC:DRIVER=FreeTDS;SERVER=x.x.x.x;PORT=1433;DATABASE=MyDB;TDS_VERSION=8.0;UID=user_id;PWD=pass")
rows = db2.execute('select * from Topic where id = 123')
rows.each { |r| puts r['name'] }
rows.finish
end
end
when I run this as:
rake RAILS_ENV=production db:test
it produces:
The Devil?s Tail
But when I run the exact same commands using:
/> script/console production
I get
The Devil`s Tail
Notice the back tick? Anyone have any idea why may be causing this? I double checked the ENV variables, and they both have LANG: en_US.UTF-8
EDIT
Forgot to mention I am using ruby 1.8.7p72 and Rails 2.3.4

Resources