RunTimeError: YAML syntax error (Unknown) - ruby-on-rails

I have started using and learning Ruby on Rails, and I wanted to use Postgres instead of sqlite3, after a bunch of stuff I went through to install the gem (I'm using Ruby 2.1.2 and Rails 4.1 in Ubuntu 14.04) when I run Rails after I create my welcome index page I got this error:
YAML syntax error occurred while parsing
/home/charlie/Documents/Projects/#potsuri/config/database.yml. Please
note that YAML must be consistently indented using spaces. Tabs are
not allowed. Error: (): found character that cannot start any
token while scanning for the next token at line 26 column 13
This is what I have in Line 26 column 13
database: #potsuri_development
This is from line 24 to line 26
development:
<<: *default
database: #potsuri_development
I'm new using Postgres so I'm not sure how to fix this "syntax error".

I don't think this has anything to do with Postgres, but, rather YAML/Ruby.
I assume by the look of it that you've got a Ruby class instance variable you're trying to interpolate into the YAML file? I think the issue is that pure YAML doesn't know anything about Ruby, and so that syntax (the # in particular) isn't expected.
The # character is reserved in YAML, so if you escaped it, i.e. \#, it would probably read it in as a literal # character, but would likely not interpolate it.
If your YAML file is being loaded in an erb (Embedded Ruby) context, and the variable you're trying to interpolate exists, then using Embedded Ruby may work to get your value in there, i.e.
database: <% #potsuri_development %>
Note: I did not downvote your question.

Related

Ruby on Rails: Difference between behaviour within the console / in a .rb file

I would like to use information stored within a the credentials.yml.enc file for a Rails 5.2 app. However, I am struggling to get a command which works perfectly within the console to behave in the same way when inserted into a .rb file.
In the Rails console (on my local development computer) Rails.application.credentials.username returns "my_username"
If I insert this line within a very simple db_backup.rb file as shown below, I get the error:
NameError: uninitialized constant #<Class:#<Backup::Config::DSL:0x00007fb0db941d10>>::Rails
db_backup.rb:
Model.new(:db_backup, 'Description for db_backup') do
##
# PostgreSQL [Database]
#
database PostgreSQL do |db|
db.username = Rails.application.credentials.username
end
end
Please could you explain why I get the different behaviour when using exactly the same line of code in the Rails console / within a .rb file?
The context in which the code is executed is not the same. One is the rails console and the other is the backup command
What happens when you load the Rails console
Launching the rails console means you launch all of the rails stack before executing your code against it. The Rack applications like Sinatra, Rails etc. use the config.ru file as a convention for which file should be run to boot. (You can explore the rabbit hole if you want to have a deep understanding of this)
It means that the vast majority of errors you can encounter when will occur during the console boot, preventing you from executing anything in the console (because boot failed). Instead it will print the stack trace errors for you to figure out what went wrong so you can correct and give it another try.
TL; DR Rails.application.credentials.username in console is executed after all of the Rails stack (models, dependencies, initializers) has loaded in a particular order
What happens when you run the backup command
The backup command is defined here in the bin repo of the backup repo
It goes like this
#!/usr/bin/env ruby
# encoding: utf-8
require File.expand_path("../../lib/backup", __FILE__)
Backup::CLI.start
If you open the required file lib/backup.rb and look around in the Gemfile, you won't fine a place where you have a dependency or a define for the Rails constant.
Thus when you run the backup command and execute your db_backup.rb, the constant Rails called here is ... not defined. Ruby being kind will try to find a nested version of this constant in the current scope which is the Model.new do; end block.
It is still not defined which ruby tells you about with NameError: uninitialized constant #<Class:#<Backup::Config::DSL:0x00007fb0db941d10>>::Rails.
#giglemad gives a great explanation of the issue of class resolution in the execution context (rails console vs. running of the backup ruby file).
To fix your error, just let the code know to use the top-level class lookup (::Rails):
Model.new(:db_backup, 'Description for db_backup') do
##
# PostgreSQL [Database]
#
database PostgreSQL do |db|
db.username = ::Rails.application.credentials.username
end
end
If you're still seeing the missing Rails constant, you'll need to put your script in either a rake task, or require your rails environment.
I ended up resolving this by simply adding the line below to the top of my db_backup.rb:
require './config/environment' # added to enable credentials to be read from Rails environment

Ruby on Rails application won’t start using Passenger when there are non-ASCII characters in the app path

I have a problem running a Ruby on Rails application using Passenger. My application resides in the /Users/Glutexo/Práce/Bytek/Bytek directory, which you can see has a non-ASCII character in in (á). Even when I symlink it into another directory, e.g. /Library/WebServer/Documents/Bytek with all characters being US-ASCII, the problem is still there.
But when I create another Rails application physically in all US-ASCII path, like /Users/Glutexo/rails/pokus, it works: The application starts and runs normally through Passenger.
The error page I get when trying to run a Rails application residing in non-ASCII path says the following:
Error message:
invalid byte sequence in US-ASCII
Exception class:
ArgumentError
Backtrace:
0 | /Users/Glutexo/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/pathname.rb | 45 | in `=~'
The line in pathname.rb mentioned is in the following function:
# chop_basename(path) -> [pre-basename, basename] or nil
def chop_basename(path)
base = File.basename(path)
if /\A#{SEPARATOR_PAT}?\z/o =~ base # This is the line no. 45
return nil
else
return path[0, path.rindex(base)], base
end
end
private :chop_basename
Does anyone have any suggestion, how to convince Passenger to be able to run Ruby on Rails application even from a path containing non-ASCII characters?
Rails is version 3.2.2, Ruby is version 1.9.3-p125, Apache is version 2.2.21, Passenger is version 3.0.12.
Thanks in advance for any help!
The solution to this problem is to add a 'magic comment' to your rails app source files. For example, at the beginning of a file that will encounter a non-ascii character, add the following:
# encoding: utf-8
There's a useful gem out there to help you do this: https://github.com/m-ryan/magic_encoding
To confirm this solution, I setup passenger with a rails app in a directory containing 'Práce' and got a similar error to you. I ran the magic_encoding gem's 'magic_encoding' command in the root of my rails app. I restarted passenger and it seems to have done the trick. Hope that helps!
See also: invalid multibyte char (US-ASCII) with Rails and Ruby 1.9

Failing to access environment variables within `database.yml` file

I have the following developement section of my development.yml file:
development:
adapter: postgresql
host: localhost
database: testtb
username: app_user
password: ENV['APP_USER_POSTGRES_PASSWORD'] <= Troublesome line
When I open a rails console via bundle exec rails console and type ENV['APP_USER_POSTGRES_PASSWORD'] I get back the DB password I've specified in my local profile. However, when I start my rails server, it can't connect to the DB, failing with
PGError FATAL: password authentication failed for user "app_user"
This was previously working when I had the DB password actually typed out in plain text, rather than trying to access it via ENV['...'], but for obvious reasons I want to keep the actual password out of this file entirely (and therefore out of the code repository) while still being able to commit other, non-secure changes to the database.yml file.
Is there something special about the syntax I'm missing, or are the environment variables for some reason not available when the database.yml file is being loaded?
Update: Some people report in the comments that this doesn't work as of Rails 4.2.x.x. I haven't tried it myself, so YMMV.
Ah, finally figured out the simple solution - it accepts embedded Ruby:
password: <%= ENV['APP_USER_POSTGRES_PASSWORD'] %>
Short and quick solution if you are running a Rails version > 4.2 Run the following command:
spring stop
..then run rails console or other rails command. My issue was that Spring server needed to be restarted in order to refresh/pickup my new ENV vars. I was starting up Rails console and it couldn't see them until I shut down Spring.
Previous versions of Rails didn't have this issue since they didn't use Spring server.
Another tool to help you troubleshoot -- Use the following command to print out your database.yml config. You can run it from the command line, but I prefer to run this within Rails console since then you can use awesome_print to make it pretty:
Within rails console:
puts ActiveRecord::Base.configurations
...or using awesome_print
ap ActiveRecord::Base.configurations
Or instead from the command line:
bin/rails runner 'puts ActiveRecord::Base.configurations'

How to identify YML parse error

I'm getting the following error when I boot my rails 3.1.3 application:
psych.rb:148:in `parse': couldn't parse YAML at line 28 column 9 (Psych::SyntaxError)
I'm guessing it is related to YML file syntax.
The problem appears when I try running:
YAML.load_file "..."
From another rails 3.1.3 application and YMLs are loaded just fine.
The syntax is covered here: http://en.wikipedia.org/wiki/YAML#Syntax
An online parser, which may help you troubleshoot, is here: http://yaml-online-parser.appspot.com/
Found a solution. If you can't find a YML syntax error in your application locale files the problem might be in some of the locale files of a gem you might be using.
I introduced a breakpoint at base.rb:15 (of rails 3.1.3) and there you can see a list of all locale yml files that will be loaded under variable filenames.
Inspecting each one I finally found a file with a

Error when loading YAML config files in Rails [duplicate]

This question already has answers here:
database.yml &references not working
(2 answers)
Closed 3 years ago.
I am configuring Rails with MongoDB, and find a strange problem when paring config/mongo.yml file.
config/mongo.yml is generated by executing script/rails generate mongo_mapper:config, and it looks like following:
defaults: &defaults
host: 127.0.0.1
port: 27017
development:
<<: *defaults
database: tc_web_development
test:
<<: *defaults
database: tc_web_test
From the config file we can see the objects development and test should both have a database field. But when it is parsed and loaded in config/initializers/mongo.db,
config = YAML::load(File.read(Rails.root.join('config/mongo.yml')))
puts config.inspect
MongoMapper.setup(config, Rails.env)
the strange thing comes: the output of puts config.inspect is
{"defaults"=>{"host"=>"127.0.0.1", "port"=>27017}, "development"=>{"host"=>"127.0.0.1", "port"=>27017}, "test"=>{"host"=>"127.0.0.1", "port"=>27017}}
which does not contain database attribute. But when I execute the same statements in a plain ruby console, instead of using rails console, mongo.yml is parsed in a right way.
{"defaults"=>{"host"=>"127.0.0.1", "port"=>27017}, "development"=>{"host"=>"127.0.0.1", "port"=>27017, "database"=>"tc_web_development"}, "test"=>{"host"=>"127.0.0.1", "port"=>27017, "database"=>"tc_web_test"}}
I am wondering what may be the cause of this problem. Any ideas? Thanks.
Depending on your system, Ruby may have been compiled with Psych support, which replaces the older Syck parser. The issue you're seeing (which only involves using a "dry" yaml file with the defaults) has already been fixed in Psych, but is not yet in a released Ruby version.
For now, you can either force the YAML parser to use Syck instead of Psych by putting this at the end of your boot.rb (but beware -- a future version of Ruby will no longer include Syck):
YAML::ENGINE.yamler = 'syck'
Or you could just use a non-DRY YAML file (without the defaults) for the time being.

Resources