Using an in-memory database within a gem - mysql

I am writing a gem that does some complex parsing/composition of a plist file.
I thought it would make sense to use the ActiveRecord interface for this and build 'structures' as an in-memory database.
The gem works fine on its own. However, I'd like to be able to incorporate it into a Rails project. The problem is that my gem calls establish_conneciton on ActiveRecord::Base which kills any previous connection the Rails app had.
It does seem to be possible because there's a section in the ActiveRecord::Base documentation titled: Connection to multiple databases in different models
This implies you can subclass from ActiveRecord::Base and call establish_connection on that. The problem then is that you can't define your schema because ActiveRecord::Schema.define uses the connection currently set on Base.
I'm thinking that the only way to do this may be to build the tables into the Rails app the includes the gem. I'd rather not go down that route if I can help it though. Any ideas?
You can view the database setup file for my gem here, if I've not made myself clear.
Many thanks

Thanks for the comments. Andrew Marshall: In this case, my tables are temporary and intended for in-memory use only.
I figured out a solution that may be of use to anyone who stumbles upon this:
Switching connection on ActiveRecord::Schema
Thanks again.

Related

Using the rails gem database_cleaner when rSpec testing and using activerecord-sqlserver-adapter

I am using the activerecord-sqlserver-adapter gem to connect to a 2008 SQL Server Database within my rails application. Please note that I do connect to multiple db's throughout my application using 'establish_connection'. I use rSpec to test my application and I want to remove the entries from the DB that rSpec creates. I googled around and found that the database_cleaner gem would be the answer to my problem so I included the Gem and setup my railsappname/spec/spec_helper.rb as so:
require 'database_cleaner'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
FactoryGirl.reload
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
I also updated the following line to be false
config.use_transactional_fixtures = false
To my rails_helper.rb RSpec.configure block as that is where that line was originally.
I have also tried changing my strategy to :truncation and that has not made a difference. The data is still being inserted in to the DB and not being deleted after the test has completed. Is this a limitation to the activerecord-sqlserver-adapter and are there workarounds for this? Is this issue being caused by the fact I connect to multiple db's within my app? I have googled around for a while and have not seen anyone else experiencing this same issue so any advise is much appreciated!
Thanks for the heads up, but your stack overflow question is really not about SQL Server or the adapter. It is really a by product of how your software is put together. I'm gonna bet it all has something to do with how you establish connections too. Check out this comment on the adapter.
https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/173#issuecomment-4427121
Basically you want to make sure you only have one model that champions a connection so you can manage it. Most gems only know about ActiveRecord::Base. So if you have an app that has many databases, please make sure you do all the things that entails. It is tricky. So much so I even wrote a blog article about it. You should read it :)
http://technology.customink.com/blog/2015/06/22/rails-multi-database-best-practices-roundup/
Lastly... this is purely subjective... but I am a big fan of Rails transactional fixtures and not running your test with an empty database. My advice:
Use Rails defaults.
Layer a small amount of MiniTest on top. Use my minitest-spec-rails gem :)
Use factory girl... but leverage them in a way for dev/test synergies. See https://github.com/metaskills/named_seeds
Again, purely subjective, but I hope that last bit helps. Cheers.

How to use import an existing Database into a Ruby on Rails 2.3.8 project in Netbeans 6.9.1

I am doing a project in which it has been imposed that I must use Netbeans 6.9.1 and Rails 2.3.8. The operating system must be Windows and we are not allowed to use the command line. We are required to use a MySQL Database (already created and fully functional) and we must import the tables from the database into models, view, and controllers in the Rails project. I don't know how we're supposed to do this because the way Rails works implies that you use the application to make the database, but we have to use the database to make the application.
I've put several dozen of hours into looking this up but I've come up empty handed because every tutorial I found for Rails either uses the command line, or uses scaffolding to create tables to put in the database instead of vice versa.
The question is, how can I generate models, views, controllers, etc. from existing database tables using only the tools in Netbeans? I'm new to both Rails and Ruby so coding them all manually would be extremely difficult because all the routes go funny. If anyone has a solution it would be most appreciated.

'Connect' a rails app to an already existing MySQL DB?

So in my company we are slowly moving to Rails instead of PHP(Code Igniter to be precise).
So, our actual PHP App is using a Mysql DB and I'd like to connect a new Rails app to this DB but meanwhile our PHP is still running, so I can't change the DB.
I don't really know where I should start to use all the rails features (Or at least as much as possible).
There shouldn't be any harm in connecting your rails app to an existing database. You will need to watch for anything that goes against rails conventions (table names are plurals of models, for example) and either change the database (and your php app) or program around the problem in rails.
But the first step is simply to connect to the database and make models for the existing tables and see what works and what doesn't.
After that, post here with any specific problems.
As a suggestion, take a backup of your database and start out programming against that to build your application and be sure everything works safely.
Well, first of all you should setup the connection in config/database.yml and then start to generate the scaffolding (models, views and controllers) table by table (check the Rails generate command). I am not really sure if you have already generated the app though. Anyway, the generator will also generate a migration script that you obviously dont want to run as the db is already there.
Hope this helps a bit.
Anyway, some resources:
http://guides.rubyonrails.org/
http://railsapps.github.io/
There are two aspects of a Rails app to consider for this scenario:
1: the database connection
Simply put the credentials for this database into database.yml.
A model like "User" will by default attempt to find records and attribute definitions in a table called "users". ActiveRecord will assume there's an auto-incrementing integer primary key on each table. When saving records, it will attempt to write to columns called created_at and updated_at. Those are a few things to be mindful of when making and using the connection.
2: the database migrations
Rails uses migration files to manage a sequence of changes to the database structure. Under normal conditions, someone building a Rails app will be starting with an empty database.
In the case of an existing database, I would recommend making a migration something like:
class BuildLegacyDbStructure < ActiveRecord::Migration
def up
Mysql2.connection.execute_some_sql_file( # made-up function
Rails.root.join('path', 'to', 'file')
)
end
def down
# reverse those changes; bring DB down to blank state
end
end
Another option would be to disable Rails/ActiveRecord's migration-based management of the database entirely. For example Rails will generate a migration when you generate a new model. So if you have an existing users table in your PHP app, and you'd like to make a rails model to use this table, you'd run something like rails generate model User --no-migration.

Trying to build rails 3.2 app over existing mysql db

I am trying to figure out how to build a rails app on top of an existing mysql db. I think the best method would just be to create a migration with the same layout as the existing db, but I am not quite sure how to do this, then connect it. I am aware of this post Building Ruby on Rails App with an existing Mysql db
but am still unsure; do I just do this but with the columns I need? Also the main answer to this question is saying that I should make my db a csv and then import it, does anyone have a tutorial or gem they recommend for that?
I have not done this exact task personally although when I modify my databases manually through my mysql client and create backup tables for example, they magically appear in my schema.rb file later down the road when I run some future migrations.
So the following post should help or at least point you in the right direction:
http://tianhsky.ueuo.com/blog/2012/02/20/generate-schema-rb-from-existing-database/
Before that, try to learn more about rails and it's conventions. Probably you'll need to adapt your database scheme.
Or you could start an application and then import the data, even by SQL or by CSV as you mentioned. Migrating data can be a tedious work, but a necessary one.
You can check this gem to see if it helps on your case, because it will depend on your actual schema.

Putting Rails over top of an existing database

I have an application written in PHP/MySQL (symfony, to be specific) that I'd (potentially) like to rewrite in Rails. I know how to create scaffolding for tables that don't exist yet, but how do I get Rails to read my existing table structure and create scaffolding based on that?
Update: it turns out I can run the following command to get Rails to generate models for me:
rails generate scaffold Bank --no-migration
But it doesn't give me forms. I would prefer something that gives me forms.
The answer is db:schema:dump.
http://guides.rubyonrails.org/migrations.html
The easiest route is to pretend that you are writing a fresh app with a similar database schema - you can then create your models and migrations with the old schema in mind, but without being restricted by it. At a later stage, you can create a database migration script to copy all the old data into the new schema.
I'm doing this right now. The benefit of this approach is that you can take advantage of all of the rapid development tools and techniques provided by Rails (including scaffolds) without being slowed by trying to retrofit to the exact same schema.
However, if you do decide that you don't like this approach, and you do need to map your new models to existing tables, there are a number of configuration options provided by active record where you can override the convention over configuration naming patterns and map model names to tables names, set oddly named ID fields etc. For example:
class Mammals < ActiveRecord::Base
set_table_name "tbl_Squirrels"
set_primary_key :squirrel_id
end
The above will help Rails attempt to read your existing table, but success will depend upon how well the existing table structures matches Rails conventions. You may have to supply more configuration information to get it to work, and even then it might not work.
Finally, it may be worth considering the use of DataMapper which I believe is more suited to existing brownfield databases than ActiveRecord, because it allows you to map everything, but of course you will need to learn that API if you don't already know it.