Ruby on Rails existing Sybase database - ruby-on-rails

I am trying to connect to an existing Sybase db using Rails and populate a few selection lists. Here's what I have done so far:
1. Installed and configured FreeTDS
2. Installed TinyTDS gem
if I execute command tsql -S serverName -U userName, I'm able to query the data. I have my config/database.yml configured as such:
development:
adapter: sybase
host: <sybase_host>
port: <port_no>
username: <user>
password: <password>
database: <db>
I then tried generating a model via rails generate model sybase_db --skip-migration and editing the created app/models/sybase_db.rb file as follows:
class SybaseDb < ActiveRecord::Base
set_table_name "my_sybase_table"
end
When I try to run SybaseDb.new command in rails console, it doesn't seem to work. I'm pretty new to Rails so what am I doing wrong?
Thanks!

Everything looks right up to the part where you generate a model called sybase_db. A model in Rails is typically linked to a specific table in a database, not the whole database. Rails uses naming conventions to simplify the linking of tables and columns to models and attributes.
For example, if you have a model User with attributes name and email that is linked to a table in your database called users and having columns name and email then all sorts of wonderful Rails magic just works. You could start the rails console and execute User.all to produce a collection of all users in the database. Or you might do something like
> u = User.find_by_email 'joe#example.com'
=> #<User id: 123, email: "joe#example.com", name: "Joe"...>
> u.name
=> "Joe"
If you have an existing database, however, chances are you're going to have to explain in more detail to Rails how to map the names in Sybase to those in your Rails system. You have one case of this in set_table_name -- if your Sybase table was named t_user with a primary key of user_id but it had columns name and email then you could create a Rails model like
class User < ActiveRecord::Base
set_table_name "t_user"
set_primary_key "user_id"
end
Here's a discussion of this topic on Quora with a couple good links that you might use to go further.
Depending on how extensive your existing system is, you may find that all of the magic of Rails goes away. Rails helps us avoid all of this mapping this to that, and follows strong naming conventions to give us all sorts of wonderful coolness. If your existing system has strong and predictable naming conventions, and isn't terribly far off from Rails' way, you might be able to use Rails successfully.

Related

Rails with two different Databases

I have used two different databases for my Rails application: MongoDB and MsSQL using Mongoid and activerecord-sqlserver-adapter adapter respectively. Everything is well but there is a problem while generate Model.
The problem is "how can I generate the model that relates to MongoDB or MsSQL differently?"
For example: I want to generate People model relates to MongoID and Animal model with MsSQL. While I generate with command: rails g model Animal name:string it generates the model related to mongoid. How can I generate the model Animal with ActiveRecord that means related to MsSQL.
Please help me.
Thanks
Based on Using Active Record generators after Mongoid installation? I believe this should work:
rails g active_record:model Animal name:string
First let me just check that I've understood your question correctly:
You have 2 databases and a series of models/migrations, and you want a way to tell rails which database to use when running a migration and accessing the database using your model?
If I'm in the right area then you need to add a method to your migration which overrides the default connection() method in ActiveRecord::Migration.
def connection
ActiveRecord::Base.establish_connection(:conn_name).connection
end
Where :conn_name is the name you gave your connection settings in config/database.yml
within your models add the line
establish_connection :conn_name
to the top of your model file and the model will now know which DB to connect to.
So the quick and dirty way that I have handled this in the past (due to my dev team keeping mongoid in the gem file for legacy reasons) is to comment out the out mongoid when you have to do migrations run a bundle, generate and run you migration then uncomment and run bundle again. This is far from best practices but it should work.

Using existing SQL Server database with Ruby on Rails

I'm on the early stages on learning Ruby.I really don't have an idea on how to use an existing database filled with tables and data on ruby. Every guide, every article that I have or find on the internet is always creating a new one using the migration functions.
But which are the steps for using an existing database in SQL server on RoR?
You're in luck, friend. My first Rails project (7 years ago) was against a horribly set up SQL Server database.
Per the above, you need to set up your database.yml appropriately. But for an existing database, obviously it is unlikely that the table and column names conform to the Rails conventions. The good news is that you can override all of those defaults. Here is a non-exhaustive list of those directives:
In a model descended from AR::Base,
set_table_name 'actual_table_name'
set_primary_key 'actual_primary_key_name'
On the various association directives (has_one, has_many, belongs_to), there are :foreign_key keys that let you specify the name of the foreign keys.
Now, one of the things that MS SQL Server allows you to do which is TERRIBLE is that you can embed spaces into your column names. Fear not, you can still refer to these columns by name using write_attribute("badly named column") and read_attribute("badly named column"). You may also refer to them in various directives like so:
validates_length_of "Fax Number", :maximum => 17, :allow_nil => true
Finally, you may refer to the implied methods these devilishly named columns generate like so:
self.send('Fax Number=', new_fax_number)
Obviously, you can't refer to them as symbols, since spaces are disallowed in Ruby symbols.
Good luck, and next time I hope that you get to work with a real RDBMS, like Informix :).
First you have to setup your application to user sql server for databases connectivity.
you have to use gem for sql server in your gemfile and have to setup database.yml file accordingly.
In database.yml, in config folder put the name of same database In the Development part of this file.
development:
adapter:
database: db_name_dev
username:
password:
host: localhost
socket:
To use a existing server. In your database.yml you have to specify the host, port and the database name.
`database: <host>:<port>/<database_name>`
For eg
development:
adapter: mysql2
database: your.mysqlserver.com:1521/project_database
username: project_user
password: project_password

Reverse Engineering (Generating) Tables or Database Schema from Models and Views in Ruby on Rails

Update: The Question is Still Open, any reviews, comments are always welcome
I am having an existing rails project in which some important files and directories has been missed.
project rails version (2.3.8) i found it in environment.rb
currently what i am having is
app
controllers (already fully coded)
helpers (already fully coded)
models (already fully coded)
reports (already fully coded)
views (already fully coded)
config ---> default configurations (already fully coded)
lib ---> contains nothing
public --> contains images and scripts (already fully coded)
script ---> contains server,runner,plugin,dbconsole....
app directory fully contains working state of codes, app/model contains more than 100 .rb files , so i assume it will be more than 100 tables
the mainly missing things are db directory, .gem file, rake file, doc, test, vendor, database,schema.rb and migrations
Note:
i don't have the table schema and database for that project
i am in Need to generate tables or complete database from models and views and
i am looking for reverse engineering kind of stuff for generating db schema from models or views
I am newbie to rails and i am from java background , in java by using hibernate there is an pojo(model in rails) to database option available, i am looking for similar kind of stuffs for rails , and my main aim to run that project , so guys please help me.
To recreate the database schema, it will take quite a bit of time.
You can get a lot of information about the database in the app/models, app/controllers app/views directory.
You should know that ActiveRecord does not require you to explicitly list all the attributes of a model. This has important implications - you can only infer what attributes you still have to add to the database, based on whether an attribute is referred to! This means doing this will be a bit of an ART. And there are no CLEAR steps to complete this work. But below are some rules which you can use to HELP you.
This is a BIG project, below are guidelines, rules and tips to help you. But be aware that this could take a long time, and be frustrating at times to get this done.
What Tables you need:
Each table will normally have a matching ActiveRecord::Base model. So in the app/models directory, check each file, and if the class inherits from ActiveRecord::Base, it is an extra table.
The table name is by default a pluralized snake case version of the name of the class.
class UserGroup < ActiveRecord::Base # for this class
the name of the table is user_groups. Notice it is plural, and instead of camel case, it is lowercase, with underscores to separate the words.
All these tables will have an "id" integer column. By default, the tables also have a "created_at", and "updated_at" column of type datetime.
Associations and foreign keys:
You can infer what foreign keys exist by the associations in the Models. All associations are explicitly listed, so this is not too hard.
For example:
class UserGroup < ActiveRecord::Base # for this class
belongs_to :category
This means that the user_groups table has a column named "category_id", which is a foreign key for the categories table.
This means that the Category model likely has an inverse relationship (but no extra column):
class Category < ActiveRecord::Base
has_many :user_groups
The main other association is the has_many_and_belongs_to association. Eg.
class A < ActiveRecord::Base
has_and_belongs_to_many :bs
end
class B < ActiveRecord::Base
has_and_belongs_to_many :as
end
This means that there is a join table to add called "as_bs" (as and bs are sorted alphabetically), with the foreign keys "a_id" and "b_id".
All foreign keys are integers.
Attributes
Ok, so that's the table associations. Now for the normal attributes...
You should check the app/views/user_groups/ or other similar app/views directories.
Inside you will find the view templates. You should look at the _form.html.erb templates (assuming it is .erb templates, otherwise it could be .haml etc templates).
The _form.html.erb template, if it exists, will normally have many of the attributes listed as form fields.
In the form_for block, check if it says something like f.text_field :name, it means there is an attribute/(column in the table) called "name". You can infer what type the column should be by what type of field it is. Eg. in this case, it is a string, so maybe a VARCHAR(255) is appropriate (referred to as string in Rails).
You might also need to infer what type is appropriate based on the name of the attribute (eg. if it mentions something like :time, then it is probably either of type Time or DateTime).
This may give you all the other attributes in the table. But in some cases, you might miss the attributes. If you find a reference to other attributes in the controller, eg. app/controllers/user_groups_controller.rb, then you should add that as a column in your table. You can leave this until the end when you test it though, because when you test it, if an attribute is missing, then it will throw a NoMethodError for the object of the relevant model. Eg. if it says that #user_group variable, of class UserGroup, is missing a method named title, then it probably is missing a column named "title" of type string.
Recreate your migration/database
Ok, so now you know what the database tables and column names and types should be.
You should generate/recreate a migration for your database.
To do this, just use the command rails generate migration RecreateTables.
Then you should find a file in db/migrate/???_recreate_tables.rb.
Inside, start writing ruby code to create your tables. Reference for this can be found at http://guides.rubyonrails.org/migrations.html.
But essentially, you will have something like:
class RecreateTables < ActiveRecord::Migration
def up
create_table :user_groups do |t|
t.string :name # adds a string (VARCHAR) column called "name"
t.text :description # adds a textarea type column called "description
t.timestamps # adds both "created_at" and "updated_at" columns for you
end
end
def down
drop_table :products # this is the reverse commands to undo stuff in "up"
end
end
To recreate your Gemfile:
Start by adding a default Gemfile. This can be done by using rails new testapplication somewhere to create an empty rails application. Then copy the Gemfile to your actual application. It will get you started by including rails and other common gems.
It is VERY hard to work out exactly what gems are needed. The best you can do is try adding them one by one as you look through the code.
Again, here, MethodNotFound errors are your FRIEND. When you test the application, based on the gems you have added, it might detect some missing methods which might be supplied by gems. Some missing methods on models might indicate missing gems (or they might indicate missing fields/columns in the database). However, missing methods on Controller or ActiveRelation classes are VERY likely because of missing gems.
You will have to look through the code and try to infer what gems to add.
If it uses methods like can, can?, and has a file app/models/ability.rb, then you need gem 'cancan'. If it calls devise in a model, it needs gem 'devise'. Many common gems can be seen at http://ruby-toolbox.com.
After adding gems to your Gemfile, you should run bundle on your command line to install the new gems before testing again. When you test it again, you should restart your test server. Rerun bundle exec rails server to start a local test server on localhost:3000 or something like that.
You can simply copy the Rakefile from rails new testapp, and it will probably include everything you need.
Missing Tests
The missing test/ directory is not relevant to your actual application. It is not required to run the application. However, it does hold automatic scripts to test your application. You will have to re-write new tests if you want to automatically test your application. However for the purpose of getting your application back up, you can ignore it for now.
Missing vendor directory
Some extra code is not installed as a gem, but as a plugin. Anything installed as a plugin is lost if you don't have the vendor directory. As with gems, the best you can do is try to infer what might be missing, and re-download the missing plugin, either re-installing the plugin, or using a gem replacement.
Additional tips:
Try reading some of the comments which might name some of the gems used.
If a method or set of methods are missing, that you think are not database fields/columns, it might be due to a missing gem. The best thing to do is to search google for those method names. Eg. if it is missing "paginate", you can search "rails paginate gem", and see what likely gems you might need. This example will probably come up with "will_paginate", and "kaminari". Then you have to try and infer which of the gems are required. Maybe do a grep will_paginate app -r on the command line to see if it is using will paginate. The grep command searches for the string "will_paginate", in the directory called "app", -r makes it do this recursively for all files
Even though rails is a full stack web framework it would work with out some parts as well, if you wish to,
Ex: in your case
db - directory is there for keep the migrations to create you DB/tables, but if you are using a legacy DB or the database stuff is handled by DB administrators, you might not want it. (you can simply connect to the DB via database.yml file)
Gem file is helping you to keep all the gems (libraries) in one place as you do with Maven (in java)
test, again if you done write test cases (which is absolutely a bad idea), you done need this
vendor, is for 3rd party plugins and doc is for documentation, so same rule applies, if you done need them you can skip them
Hibernate in rails called "Activerecord", same concept, a model is bind with a database table (technically model represents a raw in the table)
So if you really want them add them but if not just leave them
BUT, I think having a proper Gem file and test cases is a must
welcome come to Rails
HTH
In the following, I assume you already know how to:
dump your database schema into an SQL file
start a Rails console (rails c)
generate a Rails migration
Here's what I think you should do.
Identify which of your classes correspond to physical tables (you mention some views in your question, which leads me to believe a subset of your models are bound to database views instead of actual tables). To do this you need to match the definitions of your models (classes which extend ActiveRecord::Base) to CREATE TABLE statements in your schema dump. For instance, class Person in your Ruby code matches to CREATE TABLE people in your DB schema dump.
Once you identified those models (class names), you start up a Rails console and you type those model names, one at a time, and press Enter. The console output for a model called Person would presumably look like this:
>> Person
=> Person(id: integer, first_name: string, last_name: string)
You then take what's inside the parentheses, strip the leading id: integer,, get rid of commas, get rid of those blanks after the colons, thus obtaining something like this:
first_name:string last_name:string
Having done this, the command to generate the migration would look like this:
rails g migration Person first_name:string last_name:string
You then start a new Rails project somewhere else, perform all of these migrations and inspect the contents of db/migrate. Your migrations are most likely 90% done, what you still need to do is replace some instances of t.integer with t.references, and other minor stuff that's completely domain-specific and impossible to capture in a generic answer.
HTH.

Having trouble getting started with Ruby on Rails

I'm wondering if someone can address some of the issues I am having? I create a rails app:
rails myapp -d mysql
cd myapp
haml --rails .
rake db:create:all
Then I want to use a mysql client to create tables. Lets say users and customers. A customer is also a user so you have schema like this:
users
----------------
id int, not null, primary key, auto increment
first_name varchar(50) not null
last_name varchar(50) not null
email varchar(50) not null unique
password varchar(50) not null
created_at datetime not null
updated_at datetime not null
customers
----------------
id int, not null, primary key, auto increment
user_id int, unique
-- some other stuff that is customer specific
what rails script commands do I need to run to get model, views and controllers created and completely filled out under my rails app? I tried this:
ruby script/generate scaffold user
ruby script/generate scaffold customer
which creates the files but the models are empty:
class User < ActiveRecord::Base
end
whats the deal? Also, I want to create an administration section to manage stuff. I figured out that I need to add routes for those:
map.namespace :admin do |admin|
admin.resources :users
admin.resources :customers
end
what else do I need to get the administration section going?
Also here are the versions of ruby/gems I am running:
ruby 1.8.6
rails 2.3.5 & 2.3.2 <- I'm using 2.3.2 because haml
wasn't working (or some other plugin) with 2.3.5
haml 2.2.15
rspec 1.2.9 <- I saw from another thread that I might need
this when creating an adminstration section (rspec_controller etc)
Models are supposed to be empty by default because database schema is saved into the schema.rb file and managed using migrations.
From your answer I understand you are looking for a prepackage solution to write a couple of configurations and get everything, from controller to administration cooked for you.
I'm sorry, Rails doesn't offer you this feature. If you want an administration section you actually have to code it.
It includes:
creating your views and templates
creating your actions
mapping your routes
writing your tests
The scaffold only provides you a starting point but this is a starting point you should adapt and extend to your needs.
If you want the scaffold to auto-generate your initial views according to your database table, you can pass the arguments to the command line tool
ruby script/generate scaffold user name:string age:integer
But if you want to add a new field later, you'll have to write a new migration and edit your views/actions accordingly.
More information are available in the Rails Guides and Wiki.
Rails is designed for database independence with all the 'creation' done via the migrations located in db/migrate.
To create the appropriate DB tables you then simply run rake db:migrate and any migrations will be executed to create the necessary DB tables.
A good place for more information is the Rails Guides which has an example application to work through.

Rails Console Doesn't Automatically Load Models For 2nd DB

I have a Rails project which has a Postgres database for the actual application but which needs to pull a heck of a lot of data out of an Oracle database.
database.yml looks like
development:
adapter: postgresql
database: blah blah
...
oracle_db:
adapter: oracle
database: blah blah
My models which descend from data on the Oracle DB look something like
class LegacyDataClass < ActiveRecord::Base
establish_connection "oracle_db"
set_primary_key :legacy_data_class_id
has_one :other_legacy_class, :foreign key => :other_legacy_class_id_with_funny_column_name
...
end
Now, by habit I often do a lot of my early development (and this is early development) by coding for a bit and then playing in the Rails console. For example, after defining all the associations for LegacyDataClass I'll start trying things like a = LegacyDataClass.find(:first); puts a.some_association.name. Unexpectedly, this dies with LegacyDataClass not being already loaded.
I can then require 'LegacyDataClass' which fixes the problem until I either need to reload!, which won't actually reload it, or until I open a new instance of the console.
Thus the questions:
Why does this happen? Clearly there is some Rails magic I am not understanding.
What is the convenient Rails workaround?
I believe this might have to do with your model name, rather than your connection. The Rails convention is that model class names are CamelCase, while the files they reside in are lowercase+underscore.
The "LegacyModel" class should therefore be in models/legacy_model.rb. Your statement about "require 'LegacyDataClass'" indicates that this is not the case, and therefore Rails doesn't know how to automagically load that model.
I wrote something for an app at work that handles connections to other databases' at runtime, it might be able to help.
http://github.com/cherring/connection_ninja

Resources