Is it possible to obtain details about a schema and get the table objects using a stand alone active record connection. I am trying to do something like this
require'rubygems'
gem 'activerecord'
require 'activerecord'
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "root",
:database => "test_database"
)
Is it possible to access the tables of the db using this connection object.
Yes, it is perfectly possible to use ActiveRecord without Rails.
You can also use standalone_migrations gem to manage ActiveRecord environment outside of Rails: https://github.com/thuss/standalone-migrations.
Have you try to load all Active Support?
In order to have a near-zero default footprint, Active Support does not load anything by default. It is broken in small pieces so that you can load just what you need
require 'active_support/all'
Active Support Core Extensions
Related
I have an app that uses the LinkedIn gem but I need to move towards using the LinkedIn OAuth2 implementation which comes in a different gem.
I need to support the requests on oAuth1 in the initial gem for existing users, but I need to support OAuth2 for new users going forwards.
The problem is, both of these gems use the LinkedIn namespace for their module names, and depending on what order I include them in my Gemfile, one clobbers the other.
I tried adding require: false to the gemfile like so:
gem 'linkedin', require: false
gem 'linkedin-oauth2', require: false
But weirdly enough when I go to my console, the first one is still being required, where as the second one is not:
irb(main):001:0> require 'linkedin'
=> false
irb(main):002:0> require 'linkedin-oauth2'
=> true
Is this something to do with how require works? Is it possible to load just one of these gems each in separate lib files without clobbering each other?
EDIT
I figured out that I was requiring the linkedin in one of my spec files, which was causing it to be autoloaded, but that did not still fix the issue of things being clobbered.
When I have both gems installed and I run:
irb(main):001:0> require 'linkedin'
=> true
irb(main):002:0> ::LinkedIn::Client.new
NameError: uninitialized constant Api::QueryHelpers
from /Users/me/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/linkedin-1.1.0/lib/linked_in/client.rb:8:in `<class:Client>'
irb(main):004:0> require 'linkedin-oauth2'
=> true
But if I uninstall linkedin-oauth2 from my gemfile it works just fine:
irb(main):002:0> require 'linkedin'
=> true
irb(main):004:0> ::LinkedIn::Client.new
=> #<LinkedIn::Client:0x007f9eef6d72a8 #consumer_token=nil, #consumer_secret=nil, #consumer_options={}>
Why is that, especially since linkedin-oauth2 is not being required in the first example, yet the error occurs. Could it be because of how they require supporting files in the linkedin gem? Seems still like it shouldn't affect it.
I wouldn't recommend doing this, since it could have some weird side effects such as if linkedin-oauth2 references itself with ::LinkedIn, but a method to redefine a ruby constant is shown in this answer.
I would change it a little bit to prevent renaming a constant warning... Object.send(:remove_const, :Stripe) instead of the Stripe = Module.new as shown in the answer. So, an example (not tested) would be:
require 'linkedin-oauth2'
LinkedInOauth2 = LinkedIn
Object.send(:remove_const, :LinkedIn)
require 'linkedin'
I have running rails application. I cannot restart the server.
I have an environment variable that I need to change. I tried to do it through the rails console
ENV['SCORE'] = "123"
It updates variable for the current rails c session:
ENV['SCORE']
=> "123"
But has no effect on the variable that application is using.
Is there a way to permanently change environment variable at runtime?
If you want to share data between processes you typically use some kind of storage. In this situation, an in-memory key/value storage like Redis (http://redis.io/) seems optimal for your use case.
Install and run Redis, then put the gem in your Gemfile.
gem "redis"
In your code connect to the database
require "redis"
client = Redis.new
client.set("score", 123)
client.get("score")
# => "123"
client.incr("score")
# => "124"
If you create an initializer with that code
ENV['SCORE'] = "123"
the value will persist.
I'm trying to figure out how to pull data from a database without the need to place a connection string at the top of each ruby file.
I'm learning the basics of ruby via a little Sinatra app I'm putting together which pulls data from a MSSQL database.
So far I've managed to create various simple erb pages that display data from the MSSQL database by using the following code structure at the top of each file:-
<% client = TinyTds::Client.new(:username => 'name', :password => 'password', :dataserver => 'hostname', :database => 'database') %>
<% data = client.execute("SELECT * from tablename") %>
From the books, guides and online tutorials I've found based on lots of configs to do with PostgreSQL or MySQL databases it seems to me I need to be creating a central file to store my connection data (such as a database.yml file) and then referencing that somewhere/somehow in my app.
Would that be correct, and should I be doing that in my main.rb file so that each of my .erb files do not require the connection string or do I have to still refer to the database in each .erb file also?
I've noted references to creating database config variables such as:-
db_config = YAML.load(File.Open("/path_to_file/database.yml")) [ENV['RAILS_ENV']]
but that clearly seems suited to Rails apps.
Could I do something similar for my sinatra driven 'app'?
Thanks.
This should work:
require "sinatra"
require "sinatra/config_file"
config_file 'path/to/config.yml'
DB = TinyTds::Client.new(
:username => settings.name,
:password => settings.password,
:dataserver => settings.hostname,
:database => settings.database
)
get '/' do
#result = DB.do_stuff
haml :index
end
What I would suggest though, is that you look for an ORM that supports TinyTDS and use that to set up the database connection and run queries. I use Sequel a lot and I know it supports TinyTDS, but I'm sure others do too.
I'd also suggest not putting things like database settings in a file that gets checked in to source control, as it's sensitive information. I prefer to put this kind of thing into environment variables for production, and use a config file to load the environment variables in development (for convenience). Using the above example:
DB = TinyTds::Client.new(
:username => ENV["name"],
:password => ENV["password"],
:dataserver => ENV["hostname"],
:database => ENV["database"]
)
Those env variables are loaded into the production server's memory, which makes them a little bit more secure. For development, I load YAML files before starting up Sinatra, adding each value to an ENV var. I'm not suggesting this is a standard way, but it's how I do it.
Is there a way of setting the database name dynamically (coming originally from database.yml), ideally using part of the application pathname?
Background of the question is, I have a single source code that shall run on one and the same server multiple times but each instance of the application should have a different database.
Example, I have an auction site which works with the currency USD. Now I want to run the same auction site again (one the same server) for a second currency. For valid reasons I don't want to make the application multi-currency capable, I'ld like to keep the source code as is.
Setting up the application on the same server using sub-URL I will follow this approach:
http://www.modrails.com/documentation/Users%20guide%20Apache.html#deploying_rack_to_sub_uri
The question left is, how does each instance of the application get its own DB name, e.g. the one instance uses the database name production_USD and the otherone uses production_CAD
Edit: The solution works like a charm, thanks to the feedback received:
My folder structure on the server is
/var/www/auction/USD-US Dollar
/var/www/auction/CAD-Canadian Dollar
/var/www/auction/source
/var/www/logs
With the source folder containing the original source code and the USD and CAD being links to the source (no actual need for copying any code anywhere other than placing it into source.
Next to set the DB dynamically. The currency is determined automatically by looking
at the folder name. I put it into the application.rb as I need it to
in an early stage because I also want different log files for the different currencies.
I am storing the log files outside of the source folder to make sure I don't loose them
when the source folder gets refreshed from the QA system
Here the code changes:
application.rb:
fname = File.basename(File.expand_path('../../', __FILE__))
curr = fname.split("-")
if curr[1].nil?
CURR_SHORT = "XXX"
CURR_LONG = "XXX"
else
CURR_SHORT = curr[0]
CURR_LONG = curr[1]
end
dbname = "myapp_#{CURR_SHORT}_#{Rails.env[0..2]}"
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:host => "localhost",
:username => "myuser",
:password => "mypass",
:database => dbname
)
module Virex
class Application < Rails::Application
config.logger = ActiveSupport::BufferedLogger.new("../logs/#{Rails.env}.#{CURR_SHORT}.log")
....
Of course, have a look at ActiveRecord::Base.establish_connection :
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
You can put this piece of code in an initializer, with the database name you want, depending on your pathname.
Complete doc here
I'm currently using the default cookies as my single sign on (SSO) but some users are getting strange errors after I push an update. I'm considering moving to active record to store sessions but was wondering how I tell rails that the sessions are in another database?
So if I store sessions via AR in App1DB how can all the other apps know thats where to look for sessions?
Rails most certainly does support database session storage.
In config/environment.rb, uncomment
# config.action_controller.session_store = :active_record_store
Examining \actionpack-2.2.2\lib\action_controller\session\active_record_store.rb shows that CGI::Session::ActiveRecordStore::Session inherits from ActiveRecord::Base.
So at the end of config/environment.rb, you should be able to say
CGI::Session::ActiveRecordStore::Session.establish_connection(
:adapter => "mysql",
:host => "otherserver",
:username => "session_user",
:password => "123ABC",
:database => "sessions")
or
CGI::Session::ActiveRecordStore::Session.establish_connection(:sessions)
to use a connect defined in config/database.yml
For example, add to config/database.yml:
sessions_development:
adapter: mysql
host: otherserver
username: sessions_user
password: 123ABC
database: sessions
Add to the end of config/environment.rb
CGI::Session::ActiveRecordStore::Session.establish_connection("sessions_#{RAILS_ENV}")
In rails 2.3
open config/initializers/session_store.rb
uncomment the line ActionController::Base.session_store = :active_record_store
change the key's value on the line which looks like :key => '_YOUR_APP_NAME_session'
then restart your server.
The result will change your store, and invalidate all old cookies
The rails docs for the session configuration(http://api.rubyonrails.org/classes/ActionController/SessionManagement/ClassMethods.html#M000312) says that these are the only options: http://api.rubyonrails.org/classes/ActionController/Base.html#M000523. Since an option for which database to use isn't listed, it probably doesn't exist.
Can we get some clarification on your question? Do you have multiple, different, Rails apps that you want to use the same session store? I ask because you mention SSO and multiple app servers.