RubyOnRails multiple database connections errors - mysql

I have a rails application (ruby 2.0.0, Rails 4.0.1) that connects to several MySQL database.
The connection to the local database always work properly, this is my configuration:
production:
adapter: mysql
encoding: utf8
database: xxx
username: yyy
password: zzz
host: x.x.x.x
port: 3306
reconnect: true
But connections to remote databases often return an error, such as connecting to my radius external database returns the following error:
Mysql :: Error:: SELECT 1 AS one FROM WHERE `` radacct` radacct`.`username` =? LIMIT 1
Updating the page several times, the connection is restored and I can see the data properly. This is my configuration:
radius:
port: 3306
adapter: mysql
encoding: utf8
database: xxx
username: yyy
password: zzz
host: x.x.x.x
reconnect: true
connect_timeout: 60
read_timeout: 90
write_timeout: 90
checkout_timeout: 10
reaping_frequency: 30
dead_connection_timeout: 30
I tried to change the configuration of the timers in different ways, but the problem persists.
to connect to the radius server I created the following model common to all:
class RadActiveRecord <ActiveRecord :: Base
self.abstract_class = true
establish_connection "radius"
end
for example for the table radacct use the following model:
class RadAcctDetail <RadActiveRecord
self.table_name = "radacct"
end
the error in question is with any queries, such as:
def index
#rad_acct_details = RadAcctDetail.all.paginate = (
: order => "radacctid DESC"
: page => params [: page] || 1
: per_page => params [: per_page] || 25)
end
Does anyone have any suggestions?

Related

Accessing another database wtih SQL queries

I am attempting to access another database in my rails app, as well as query that database with SQL statements and return JSON.
The main database and secondary are on the same server running in MySQL. When testing to see if this would simply work as:
The datagbase.yml file:
development:
adapter: mysql2
encoding: utf8
database: onlineportal
username: root
password:
host: 127.0.0.1
port: 3306
socket:
android_mobile_developement:
adapter: mysql2
encoding: utf8
database: androidchatterdatabase
username: root
password:
host: 127.0.0.1
port: 3306
socket:
but then building out the method in the controller:
class RequestsController < ApplicationController
def getActivatedFriends
#results = User.find_by_sql("SELECT
a.id
, a.username
, a.phoneNumber
FROM androidchatterdatabase.users a
WHERE phoneNumber in (8754444444) and
removed = 0 and
is_user = 1;")
respond_to do |format|
format.html
format.json { render json: { friends_match: #results }}
end
end
and calling the route:
localhost:3000/getActivatedFriends/
from the routes:
match '/getActivatedFriends/', to: 'requests#getActivatedFriends', via: 'get'
yields the error:
Missing template requests/getActivatedFriends, application/getActivatedFriends with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}.
While sending the request, send it as local host:3000/getActivatedFriends.json.That way controller will respond to json request. By default it responds to html request.
You can access another database by specifying the database name before the table, such as:
SELECT * FROM onlineportal.table
- or -
SELECT * FROM androidchatterdatabase.table
Is this what you're looking to do? If they're on the same server this syntax would work.

db:migrate does not create tables

Working with:
Ruby 1.9.3
Rails 4
MySQL 5.6
Whenever I run "rake db:migrate" no tables are created in the database.
I have created a database and named it "simple_cms_development" and changed the development part of "database.yml" accordingly:
development:
adapter: sqlite3
database: simple_cms_development
pool: 5
username: simple_cms
password: ruby
timeout: 5000
I generated and model named "User" and edited "create_users.rb" to:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string "first_name", :limit => 25
t.string "last_name", :limit => 50
t.string "email", :default => "", :null => false
t.string "password", :limit => 40
t.timestamps
end
end
end
I run "rake db:migrate" and there is no change to the tables within the database. When I run SHOW TABLES; in MySQL I get back "Empty set (0.00sec)". I don't even get "schema_migrations" table.
Any ideas what is going on?
Thanks!
Your database.yml is set up to use sqlite3, not mySQL. Yours is now this:
development:
adapter: sqlite3
database: simple_cms_development
pool: 5
username: simple_cms
password: ruby
timeout: 5000
You should probably be using the mySQL2 gem, and your database.yml should look something like this:
development:
adapter: mysql2
encoding: utf8
reconnect: false
database: simple_cms_development
pool: 5
username: root
password: your-password
socket: /var/run/mysqld/mysqld.sock
According to this StackOverflow discussion you can get your socket by running
mysqladmin variables | grep socket
or if you have a password on your root:
mysqladmin password-here variables | grep socket`
If you want to use host and port instead of socket try this:
development:
adapter: mysql2
encoding: utf8
reconnect: false
database: simple_cms_development
pool: 5
username: root
password: your-password
host: 127.0.0.1
port: 3306
Here is a blog with instructions on how to set up mySQL with Rails 3.2, it might help with your Rails 4 issue: http://cicolink.blogspot.com/2011/06/how-to-install-ruby-on-rails-3-with.html

Check mysql connection to remote host

I have model to store database connection parameters (host, database name, username, password) and filling it by form. Before create or update I need to check if connection be good with entered parameters. I create validate :check_connection validator:
# don`t change primary connection
class Remote < ActiveRecord::Base; end
def check_connection
return if errors.any? || (!new_record? && password.empty?)
begin
Remote.establish_connection(
adapter: 'mysql2',
host: host,
username: username,
password: password,
database: database,
connect_timeout: 5,
reconnect: false
)
# maybe need to make some sql request? did try it
rescue Exception => e
errors.add :connection, 'Could not connect to database'
end
end
When I try enter accessible host (localhost), code like above works good. But if host like 192.168.1.1 (unaccessible) page freezing after submit form. I see attempts to connect every second and it did not stop after ESC (stop loading page) at browser (I see attempts at tcpdump on network interface). And attempts did not stop..
So, how can I validate connection to database? And if connection can not be established page must will not be load long time.
I did use gem 'mysql2' and bundle install 0.3.11 version. This version ignore connect_timeout and bug fixed at newer version. After I try 0.3.12b4 (gem 'mysql2', '~> 0.3.12b4') all works fine.
Variable connect_timeout is a global variable. Therefore, mysql2 maybe ignore it.
on mysql5.6:
mysql[(none)]> set connect_timeout = 123;
ERROR 1229 (HY000): Variable 'connect_timeout' is a GLOBAL variable and should be set with SET GLOBAL
I set timeout variables when initializing mysql2 but it's not reflected. A README of mysql2 says that you can set the *timeout options, but I think the README is outdated or broken.
on mysql2 0.3.14(gem):
client = Mysql2::Client.new(
host: 'localhost',
database: 'test',
username: 'root',
password: '',
connect_timeout: 3,
read_timeout: 3,
write_timeout: 3,
wait_timeout: 3);
client.query('show variables like "%timeout%"').map{|r| [r["Variable_name"], r["Value"]] }
=> [["connect_timeout", "10"],
["delayed_insert_timeout", "300"],
["innodb_lock_wait_timeout", "50"],
["innodb_rollback_on_timeout", "OFF"],
["interactive_timeout", "28800"],
["lock_wait_timeout", "31536000"],
["net_read_timeout", "30"], # Maybe older mysql has read_timeout?
["net_write_timeout", "60"], # Maybe older mysql has write_timeout?
["slave_net_timeout", "3600"],
["wait_timeout", "28800"]]
If you use ActiveRecord, you can set only wait_timeout variable by database.yml.
in database.yml:
development:
adapter: mysql2
encoding: utf8
charset: utf8
database: test
pool: 5
username: root
password:
host: localhost
connect_timeout: 3
read_timeout: 3
write_timeout: 3
wait_timeout: 3
A result of ActiveRecord 4.0.1:
> ActiveRecord::Base.connection.execute('show variables like "%timeout%"').to_a
=> [["connect_timeout", "10"],
["delayed_insert_timeout", "300"],
["innodb_flush_log_at_timeout", "1"],
["innodb_lock_wait_timeout", "50"],
["innodb_rollback_on_timeout", "OFF"],
["interactive_timeout", "28800"],
["lock_wait_timeout", "31536000"],
["net_read_timeout", "30"],
["net_write_timeout", "60"],
["rpl_stop_slave_timeout", "31536000"],
["slave_net_timeout", "3600"],
["wait_timeout", "3"]]
ActiveRecord set wait_timeout variable in abstract_mysql_adapter.rb.
see:
abstract_mysql_adapter.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
mysql2_adapter.rb
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb

Are database read_timeout and write_timeout unique to ActiveRecord or native to mysql?

ActiveRecord allows you to configure database read_timeout and write_timeout values, for example:
production:
adapter: mysql
encoding: utf8
database: mydb
pool: 5
username: myuser
password: mypass
host: myhost
write_timeout: 2
read_timeout: 10
Are read_timeout and write_timeout unique to ActiveRecord, or are those part of the mysql spec? I know that mysql has the concept of innodb_lock_wait_timeout, but I don't believe that is the same as query timeouts.
Thanks!
I have never used mysql gem. But I think you can see mysql variables which are used by ActiveRecord like this.
> ActiveRecord::Base.connection.execute('show variables like "%timeout%"').to_a
=> [["connect_timeout", "10"],
["delayed_insert_timeout", "300"],
["innodb_flush_log_at_timeout", "1"],
["innodb_lock_wait_timeout", "50"],
["innodb_rollback_on_timeout", "OFF"],
["interactive_timeout", "28800"],
["lock_wait_timeout", "31536000"],
["net_read_timeout", "30"],
["net_write_timeout", "60"],
["rpl_stop_slave_timeout", "31536000"],
["slave_net_timeout", "3600"],
["wait_timeout", "2147483"]]

Multiple DB connection in rails

I am trying to connect multiple database in ROR application.My database.yml is look like this
in your database.yml file
development:
adapter: mysql
username: root
password:
database: example_development
private:
adapter: mysql
username: root
password:
database: example_private_development
It is possible to connect using establish_connection :private
My doubt is that how use rake db:create.I am not able get solution from google.
Please help me to clear it.
Try
rake db:create:all
And yes, it's possible to have multiple db connections in a Rails application.
This is what I did once, I have created two classes which inherit from ActiveRecord::Base and set the connections inside those classes.
Then I inherited all my models in one of those classes instead of direct ActiveRecord
Below is an example:
database.yml file
#app uses two database
#1 - test1
#2 - test2
test1:
adapter: mysql
encoding: utf8
database: test1
username: root
password: xxx
host: localhost
test2:
adapter: mysql
encoding: utf8
database: test2
username: root
password: xxx
host: localhost
Then I have two models for both test1 and test2 databases:
class Test1Base < ActiveRecord::Base
self.abstract_class = true
establish_connection("test1")
end
class Test2Base < ActiveRecord::Base
# No corresponding table in the DB.
self.abstract_class = true
establish_connection("test2")
end
Then I inherit my models according to database:
class School < Test1Base
#code
end
class Student < Test2Base
#code
end
Thanks for reply.
we can migrate a model for particular DB, for example
db:migrate RAILS_ENV="portal_development"'.
And more change for establishing connection with DB.check the corrected below
class Test1Base < ActiveRecord::Base
self.abstract_class = true
establish_connection :development
end
class Test2Base < ActiveRecord::Base
# No corresponding table in the DB.
self.abstract_class = true
establish_connection :portal_development
end
Thanks sameera for your valuable reply.
cheers
Shamith c
Possibly use active_delegate?
http://railslodge.com/plugins/595-active-delegate