Database.yml configuration options - ruby-on-rails

I would like to know where I can read about valid configuration options for database.yml for ActiveRecord. I know the basic ones like adapter, database, username, password, etc., but I would like to have the full list for each adapter. Where would I find that?

I found a gist of database.yml examples using mysql, postgres, and sqlite3, and the Rails 3.2 source code for connection adapters provides good insight as well.
Looks to me that the following are the most widely used options:
adapter
encoding
database
pool
username
password
socket
host
port
timeout
The Rails 3.2 connection_specification.rb file looks like it simply merges any options you include, so I'd say what options you include are dependant on the database adapter you choose to use (lines 58-74):
def connection_url_to_hash(url) # :nodoc:
config = URI.parse url
adapter = config.scheme
adapter = "postgresql" if adapter == "postgres"
spec = { :adapter => adapter,
:username => config.user,
:password => config.password,
:port => config.port,
:database => config.path.sub(%r{^/},""),
:host => config.host }
spec.reject!{ |_,value| !value }
if config.query
options = Hash[config.query.split("&").map{ |pair| pair.split("=") }].symbolize_keys
spec.merge!(options)
end
spec
end

Related

Using the backup gem how can I get database authentications details from rails database.yml

I'm testing out the backup gem
http://backup.github.io/backup/v4/utilities/
I understand that I've to create a db_backup.rb with the configuration for example
Model.new(:my_backup, 'My Backup') do
database MySQL do |db|
# To dump all databases, set `db.name = :all` (or leave blank)
db.name = "my_database_name"
db.username = "my_username"
db.password = "my_password"
db.host = "localhost"
db.port = 3306
However I'm not able to find out how to get those details from the Rails database.yml. I've tried something like this:
env = defined?(RAILS_ENV) ? RAILS_ENV : 'development'
#settings = YAML.load(File.read(File.join( "config", "database.yml")))
But I guess there should be a better way.
I would do something like this:
env = defined?(RAILS_ENV) ? RAILS_ENV : 'development'
config = YAML.load_file(File.join('config', 'database.yml'))[env]
Model.new(:my_backup, 'My Backup') do
database MySQL do |db|
config.each_pair do |key, value|
db.public_send("#{key}=", value)
end
# ...
Use ActiveRecord's own configuration handling:
require 'active_record'
require 'yaml'
Model.new(:my_backup, 'My Backup') do
database MySQL do |db|
config = {
# these are the default values
host: 'localhost'
port: 3306
}.merge(load_configuration(ENV['RAILS_ENV'] || 'development'))
config.each_pair do |key, value|
db.public_send("#{key}=", value)
end
end
# this loads the configuration from file and memoizes it
def load_configuration(env)
#file_config ||= YAML.load(File.read(File.join( "config", "database.yml")))
#configurations ||= ActiveRecord::ConnectionHandling::MergeAndResolveDefaultUrlConfig.new(file_config).resolve
#configurations[env]
end
end
The key advantage here is that it will merge the values from ENV['DATABASE_URL']. Which is very important since you should avoid adding database credentials to config/database.yml.
A good habit is to specify only the connection adapter and base essentials in database.yml. Use ENV['DATABASE_URL'] for usernames, passwords and everything else.
Env vars are easy to change between deploys without changing any
code; unlike config files, there is little chance of them being
checked into the code repo accidentally; and unlike custom config
files, or other config mechanisms such as Java System Properties, they
are a language- and OS-agnostic standard.
- https://12factor.net/config
See:
Configuring Rails Applications

Configure Redis connection on initialize

I'm using Predictor gem and when I attempt to start the gem shows:
"redis not configured! - Predictor.redis = Redis.new" (RuntimeError)
So, how to configure Redis Connection on initialize?
thank's
This is how Redis is initialized in general.
Firstly, a good practice would be adding this to your config/environments/[environment_name].rb. So you can maintain different locations for Redis when you change environments.
config.redis_host = "localhost"
Then in your application's config/initializers path create redis.rb and place the code below to initialize Redis.
require 'redis'
## Added rescue condition if Redis connection is failed
begin
$redis = Redis.new(:host => Rails.configuration.redis_host, :port => 6379)
rescue Exception => e
puts e
end
Then you'll be able to use the global variable $redis within your application for Redis-related commands.
$redis.hset "my_hash", item.id, business.id
Here is a helpful article with more details.
Now in your case as this documentation suggests, here is what you should do:
In config/initializers/predictor.rb,
Predictor.redis = Redis.new(:url => ENV["PREDICTOR_REDIS"])
Or, to improve performance, add hiredis as your driver (you'll need to install the hiredis gem first)
Predictor.redis = Redis.new(:url => ENV["PREDICTOR_REDIS"], :driver => :hiredis)
Then, be sure to include include Predictor::Base in all models you want to use it,
class CourseRecommender
include Predictor::Base
...
end
Here is the code responsible for the error you getting.

Copy between databases in Rails console

I have three databases:
A. mynewapp_psql (Postgres)
B. old_products_psql (Postgres)
C. old_blogposts_mysql (Mysql)
Each is defined in database.yml
I'm using A (mynewapp_psql) as the database for my new app. In this app I want to be able to copy selected material from my two older databases.
My attempt (updated according to response)
old_db = ActiveRecord::Base.establish_connection(:database => 'old_blogposts_mysql'... etc)
posts = old_db.connection.execute("select * from posts'")
posts.each do |p|
NewPost.create(:name => p.name.downcase) #NewPost should add Post in A. (mynewapp_psql)
end
It should take each product from my old database and create a new equivalent in the new database.
I really prefer doing it through the console and I can't copy the database straight over since I need to filter and alter the data.
So your case is one of Lost connection. How about Establishing a new connection to your current DB so that your code becomes like this
old_db = ActiveRecord::Base.establish_connection(:database => 'old_blogposts_mysql'... etc)
posts = old_db.connection.execute("select * from posts'")
new_db = ActiveRecord::Base.establish_connection(:database => 'mynewapp_psql'... etc)
posts.each do |p|
NewPost.create(:name => p.name.downcase) #NewPost should add Post in A. (mynewapp_psql)
end
The console is not the only way to dynamically access your databases. Think about a custom ruby task for your purposes using ActiveRecord connections for each database.
require 'pg'
require 'active_record'
ActiveRecord::Base.establish_connection(
adapter: 'postgresql', # or 'mysql2' or 'sqlite3'
host: 'localhost',
database: 'canvas_test',
username: 'joe',
password: 'shiitake'
)
# EXEC raw SQL
ActiveRecord::Base.connection.execute("SELECT * FROM posts;")
class Post < ActiveRecord::Base
end
# READ all posts
puts Post.count
=> #<Post:0xb96582cc>
=> ...
# CREATE one new post
my_post = Post.new

How do I configure Rails to disable sending real emails out while in staging?

I'm on Heroku, and emails don't get sent out in development, but are properly being sent in production. I'd like to run a seperate staging instance on Heroku, but don't want emails being sent out (just to a log).
This line in test.rb tells ActionMailer not to deliver emails:
config.action_mailer.delivery_method = :test
Instead, they are accumulated in the ActionMailer::Base.deliveries array.
You'll need to set up a staging environment for your application and configure Heroku to use that environment on your staging instance.
Applications that use the Mail gem (including rails >= 3.0 projects) can use the safety_mailer gem. Specify a domain (or set of domains, or magic word in email address) email is allowed to go to, and email to all other domains is silently dropped.
https://github.com/cluesque/safety_mailer
Add the gem to your Gemfile, specifying groups (probably not production) to include it in.
gem "safety_mailer", :group => :development
Don't forget to bundle install to install
In your environment file config/environments/development.rb configure it, and some regular expressions.
config.action_mailer.delivery_method = :safety_mailer
config.action_mailer.safety_mailer_settings = {
allowed_matchers: [ /mydomain.com/, /mytestacct#gmail.com/, /super_secret_test/ ],
delivery_method: :smtp,
delivery_method_settings: {
:address => "smtp.mydomain.com",
:port => 25,
:domain => "mydomain.com",
:authentication => :plain,
:user_name => "mydomain_mailer#mydomain.com",
:password => "password"
}
}
... and now, email to anyone#mydomain.com, mytestacct#gmail.com, bob+super_secret_test#yahoo.com all get sent
and email to other recipients (like the real users in the production database you copied to a test server) is suppressed.
You might be interested in mailtrap.io (disclaimer: I am affiliated with this product). It is a perfect tool to test email deliveries in development and production. All you have to do is set mailtrap.io as an smtp server in your staging environment config:
config.action_mailer.smtp_settings = {
:address => "mailtrap.io",
:port => 2525,
:authentication => :plain,
:user_name => "LOGIN",
:password => "PASSWORD"
}
Having this all your test emails sent in staging env will be stored in mailtrap for view and sharing. But non of them will be sent to the real addresses. You can use it in development as well.
And by way - it's totally free!
put this in your environment.rb file
config.action_mailer.delivery_method = :test
It should stop sending mail to the mail server, I think there is a :log option, but I have not tried it out.
I see people suggest using Mailtrap.io. Good alternative is Debug Mail. Using is quite simple.
We use maildev, which you can install locally. Great for development and staging environments, easy to install in a variety of tech stacks.
Depending on your choices
If you want a convenient way of receiving emails for debugging, etc. I recommend https://github.com/fgrehm/letter_opener_web, which will save emails locally, and provide an URL to browse emails that were sent. No email is sent outside, and you can very conveniently see the output in your browser
If you want to be able to open email files with your email clients, you should choose a :file adapter for ActionMailer (configure in config/environments/your_env.rb)
If you want a real production-like environment, I'd suggest to configure an email interceptor that would rewrite the TO/CC/BCC to a real mailbox of your choice, this way you can keep and test your original ActionMailer adapter
if Rails.env.staging?
class TestEmailsInterceptor
def self.delivering_email(mail)
mail.to = ['My Test Box <test-box#example.com>']
# remove bcc, cc, etc.
end
end
ActionMailer::Base.register_interceptor(TestEmailsInterceptor)
end

RSS feed from MySQL table using either Ruby or Rails or Gems

I have a MySQL table and I want to pick certain columns to create RSS Feed from it. How to do it using Ruby or Rails or Gems?
Depending on what I was trying to do, I would probably just go for a simple Ruby script. I would use ActiveRecord so I didn't have to write any SQL. Then I would use either Builder or RubyRSS to generate the feed.
Connecting ActiveRecord to a MySQL server directly is as simple as:
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "myusername",
:password => "mypassword",
:database => "mydb"
)
Then you are free to define ActiveRecord models like you would in a regular Rails app.
There are RSS generator examples on the RubyRSS website and a Builder one on the Railscasts website.
Hernan is right...here is are the full steps you'll need to get data from the database (I moved the code to below the steps for easier formatting:
Install ActiveRecord: sudo gem install activerecord
Establish the connection per hernan43's recommendation (preferrably in a separate file, let's call it "connection.rb"
Create a class that uses that connection by inheriting from ActiveRecord
Retrieve record(s) from the table, and use it/them to populate your RSS generator
You don't have to separate everything out into a file...you could put everything below in one file, and remove the 'requires' in files 2 and 3, but it's a convention to separate out your concerns in a manner similar to what I've done.
#1: file connection.rb
require 'rubygems'
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:database => "appdb",
:username => "appuser",
:password => "secret"
)
#2 filename: singural_rss_table_name.rb
require 'connection'
class SingularRSSTableName < ActiveRecord::Base
set_table_name 'real_database_table_name' #if the table name is the lowercase, underscore plural of the class name, then you don't need this line.
end
#3 filename: rss_creator_file.rb
require 'singular_rss_table_name'
# Here you retrieve the rows from your database table,
# based on the condition that the column 'title' is exactly the text 'article_title'
# there are a lot more options for
# conditions in ActiveRecord, and you'll probably want to look them up.
records_for_rss_entries = SingularRssTableName.find(:all, :conditions => {:title => 'article_title'})
rss_object = RSS::Maker.new(version) do |feed|
feed.channel.title = "Example Ruby RSS feed"
records_for_rss_entries.each do |entry_record| # here we're iterating through
# each of the rows we found.
entry = feed.items.new_item
entry.title = entry_record.title # at this point, each 'entry_record' is a row in your db table
# use the dot (.) operator to access columns in the table.
...
end
end
The contents of this answer were partially answered from:
http://rubyrss.com/
and
http://www.agileadvisor.com/2008/01/using-activerecord-outside-rails.html

Resources