Do I need a connection to use ActiveRecordObject.new? - ruby

Can you create and initialize an ActiveRecord object like this?
exercise = Exercise.new
exercise.name = "foo"
exercise.description = "bar"
exercise.unit_id = 123
I am trying to do this and I keep getting
ActiveRecord::ConnectionNotEstablished - ActiveRecord::ConnectionNotEstablished:
/usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:326:in `retrieve_connection'
/usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_specification.rb:123:in `retrieve_connection'
/usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_specification.rb:115:in `connection'
/usr/lib/ruby/1.8/active_record/base.rb:1271:in `columns'
/usr/lib/ruby/1.8/active_record/base.rb:3014:in `attributes_from_column_definition_without_lock'
/usr/lib/ruby/1.8/active_record/locking/optimistic.rb:55:in `attributes_from_column_definition'
/usr/lib/ruby/1.8/active_record/base.rb:2434:in `initialize'
main.rb:14:in `new'
I just want to create and initialize the object then call a .save method. If I am going about this incorrectly, please let me know.

Short Answer: Yes, you need a connection!
You cannot (generally) use ActiveRecord unless there is a connection.
The set of attributes on the object is determined by the columns on the table. Which means you can't use the object unless you have the connection.
In any case what would happen after calling exercise.save if there is no connection?
So if you only need the validation, you can reuse ActiveSupport::Validation on a transient class.

This would imply that Rails cannot connect to your database. Ensure your database server is on (if applicable), and that your config/database.yml file is correct.

Try this at the top of your code
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "<your database username>",
:password => "<your database password>",
:database => "<your database name>"
)
The above code should establish an ActiveRecord database connection to your database. You can check out the manual for it here http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-c-establish_connection. Good luck!

Related

Preventing an Instance Method from Printing to Console

I am writing a simple Ruby script that utilizes the mysql2 gem.
In order to properly terminate a connection with the database and avoid the Too many connections error, I store my connection into the variable mysql like so:
mysql = Mysql2::Client.new(:host => hst, :username => usr, :password => pass, :database => db, :connect_timeout => 30)
and then I close the connection:
mysql.close
When this occurs, I get:
closed MySQL connection
in the console.
How can I implement the Instance Method #close found here without closed MySQL connection showing up in the terminal?
you can do this:
def silence_stdout
$stdout = File.new( '/dev/null', 'w' )
yield
ensure
$stdout = STDOUT
end
and do the close with that method
silence_stdout{mysql.close}

uninitialized constant Couch::Couchbase (NameError)

I have this problem:
uninitialized constant Couch::Couchbase (NameError)
./features/step_definitions/lib/couchbase.rb:6:in `get'
./features/step_definitions/StepsLib.rb:130:in `/^I get couch$/'
features/test.feature:4:in `Then I get couch
The code is:
require 'rubygems'
require 'couchbase'
class Couch
def get
client = Couchbase.connect(:bucket => "user", :hostname => "192.168.1.50")
user = client.get("COMMENT-FO-1103")
return user
client.disconnect
end
end
I've been loocking all over, and no clue, I'm no ruby expert.
Thanks.
Try connecting through IRB and see if you get the same error.
Open up an IRB instance and type:
> require 'Couchbase'
You'll get a statement back saying: => true
Then connect as follows:
> c = Couchbase.new("http://localhost:8091/pools/default/buckets/MyBucket")
This should connect you directly to the bucket you wish to operate on.
Then try:
> c.set("mykey", "Some Value")
And you should get a confirmation that the object has been set in the Bucket.
Then use:
> c.get("mykey")
And you should print the value of the object you just set.
Regarding your code above, I'm not sure why exactly you're trying to wrap this call up in a Class? What is your Use case?
I notice on the github page that methods like get aren't run on client itself, but instead are used in a block argument to run like:
client.run { |conn| conn.get("COMMENT-FO-1103") }
That's really all I can think of there. Hope it helps.
I do notice that return user will prevent the line client.disconnect from ever running, as return kicks you out of the method entirely.

Unable to rescue from Redis connection refusal

I am attempting to write a function which tries to connect to Redis using default TCP settings, and if that fails, tries to connect to Redis through a unix socket. My intent is to have a single connection script that works on all my systems, some of which use TCP and others which use sockets.
However, I can't seem to rescue from the failed TCP connection. Here is my test script.
require "redis"
def r
begin
$redis ||= Redis.new
rescue
$redis = Redis.new(:path => "/tmp/redis.sock")
end
end
puts "You have #{r.keys.count} redis keys"
The rescue block never gets executed and instead an exception is raised. Here is the output of this script.
/usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:236:in `rescue in establish_connection': Connection refused - Unable to connect to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED)
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:222:in `establish_connection'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:23:in `connect'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:247:in `ensure_connected'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:137:in `block in process'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:206:in `logging'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:136:in `process'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:46:in `call'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis.rb:246:in `block in keys'
from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis.rb:245:in `keys'
from scripts/redis.rb:11:in `<main>'
I have verified that Redis.new(:path => "/tmp/redis.sock") works as expected. I have tried to be more specific with my rescue block by using rescue Errno::ECONNREFUSED to no avail. I'm not sure why I cannot catch this exception.
Any ideas?
It turns out the exception is not being thrown when calling Redis.new. The exception doesn't get thrown until certain methods (in this case, Redis#keys) on the connection object are called. This revised connection function appears to do the trick.
require "redis"
def r
begin
$redis ||= Redis.new
$redis.inspect # needed to know if connection failed
rescue
$redis = Redis.new(:path => "/tmp/redis.sock")
end
$redis
end
I found that $redis.inspect didn't actually exercise the REDIS connection. I replaced it with $redis.keys and that correctly threw the exception. Note, am running on Heroko and it passes in the environment variable REDISTOGO_URL. I then have a constant REDIS that I use throughout the application.
In my config/initializers/redis.rb:
uri = URI.parse(ENV['REDISTOGO_URL'])
begin
redis ||= Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
redis.keys # needed to know if connection failed
REDIS = redis
rescue
puts("Redis not loaded on #{uri.port}")
REDIS = nil
end

(Ruby) ActiveRecord with PG try to connect with local user to remote server

I made a simple-coding-ruby-program for get backups from remote server, and I made a db in postgresql for save information and schedule backups.
The connect with DB was done with ActiveRecord, I configured for access a internal DB (in other server), but when I try to connect to remote db, i get this message:
/usr/lib/ruby/1.8/active_record/connection_adapters/postgresql_adapter.rb:968:in `initialize': FATAL: no existe el rol <<mi_user_name>> (PGError)
from /usr/lib/ruby/1.8/active_record/connection_adapters/postgresql_adapter.rb:968:in `connect'
from /usr/lib/ruby/1.8/active_record/connection_adapters/postgresql_adapter.rb:968:in `connect'
from /usr/lib/ruby/1.8/active_record/connection_adapters/postgresql_adapter.rb:217:in `initialize'
from /usr/lib/ruby/1.8/active_record/connection_adapters/postgresql_adapter.rb:37:in `new'
from /usr/lib/ruby/1.8/active_record/connection_adapters/postgresql_adapter.rb:37:in `postgresql_connection'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:223:in `send'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:223:in `new_connection'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:245:in `checkout_new_connection'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:188:in `checkout'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:184:in `loop'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:184:in `checkout'
from /usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:183:in `checkout'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:98:in `connection'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_pool.rb:326:in `retrieve_connection'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_specification.rb:123:in `retrieve_connection'
from /usr/lib/ruby/1.8/active_record/connection_adapters/abstract/connection_specification.rb:115:in `connection'
from /usr/lib/ruby/1.8/active_record/base.rb:3113:in `quoted_table_name'
from /usr/lib/ruby/1.8/active_record/base.rb:1684:in `construct_finder_sql'
from /usr/lib/ruby/1.8/active_record/base.rb:1548:in `find_every'
from /usr/lib/ruby/1.8/active_record/base.rb:1505:in `find_initial'
from /usr/lib/ruby/1.8/active_record/base.rb:613:in `find'
from main.rb:84:in `main'
from main.rb:126
PG try to connect to remote db with my local user, in the declaration of ActiveRecord I set the parameters:
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "postgresql",
:host => "xxx.xxx.x.101",
:port => 5432,
:database => "VB_DB",
:user => "pg_user",
:password => "blahblah"
)
I working with Ruby 1.8.7.
Any idea about this?
thank for reading, and help me.
Grettings.
EDIT
I found the solution:
ActiveRecord::Base.establish_connection(
:adapter => "postgresql",
:host => "xxx.xxx.x.101",
:port => 5432,
:database => "VB_DB",
:username => "pg_user",
:password => "blahblah"
)
I used :user and must be :username.
Shame on me.
From the error message, it appears that Postgres doesn't think your user exists in the database.
A good first step to troubleshoot this is to try connecting without involving Ruby at all. Since the 'psql' command-line client uses the same underlying library (assuming you're using the 'pg' gem to connect), in general if you can connect using that, you should be okay to connect from Ruby as well.
Try this:
psql -h xxx.xxx.x.101 -U pg_user -W -l
If this shows you the same error (no existe el rol <<mi_user_name>>), then you'll need to confirm that your user exists, and create it.
If it shows you a list of databases, we'll have to try something else.

net-ssh and ActiveRecord 3: bringing it all together

I'm working on a small Ruby program that will connect to a remote MySQL Bugzilla database, perform a query of records, and email details of those records to a group on a daily basis.
So far, I've been able to SSH to the db server and execute a command using net-ssh. Here's an example:
require 'net/ssh'
Net::SSH.start("db.example.com", "sroach", :password => "secret") do |ssh|
result = ssh.exec!("ls -l")
puts result
end
That outputs just fine.
Using ActiveRecord 3.0.3, I wanted to test the establish_connection method so I established a connection to my local MySQL database and was able to execute commands using ActiveRecord. Example:
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "mysql2",
:host => "localhost",
:database => "list_tool_development",
:username => "my_username",
:password => "secretpassword"
)
class MailingList < ActiveRecord::Base
end
MailingList.first #=> Successfully retrieves first record from the table
So, where I'm having trouble is bringing it all together and applying it to my remote MySQL db. Here's my best try thus far:
require 'net/ssh'
Net::SSH.start("db.example.com", "sroach", :password => "secret") do |ssh|
ssh.forward.local(3307, "127.0.0.1", 3306)
ssh.loop { true }
end
But all that does is make my IRB session hang (which could be completely normal...don't know). Incase that hang was normal, I opened a new IRB session and tried to establish a connection to the remote database like so:
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "mysql2",
:host => "127.0.0.1",
:port => 3307,
:reconnect => false,
:database => "bugs",
:pool => 5,
:username => "my_username",
:password => "secret",
:socket => "/tmp/mysql.sock"
)
class Bug < ActiveRecord::Base #=> the table name in the "bugs" db is "bugs"
end #=> so I made the model singular
Bug.first #=> the IRB session hangs at this point
So, I have no idea what's going wrong or how to degub it. Any and all suggestions would be helpful.
I'm on Mac OSX. The db that I'm trying to connect to is on FreeBSD 7.0 and is MySQL version Ver 14.12 Distrib 5.0.67.
Rather than try to tunnel the ActiveRecord connection inside SSH, have you tried connecting directly from ActiveRecord to the DB server? That is the normal way to connect across a network and is directly supported by ActiveRecord.
Replace the host ID with the server host IP or DNS entry, the port can probably be allowed to default to the MySQL driver's default of 3306, and the socket isn't needed since the DB is on the remote host.
If the DB host isn't on the same network as yours, and you're crossing firewalls, you might need to have that port opened to allow the connection. If it is on the same network it should work without needing ssh at all.

Resources