In mongodb,How to use ruby on rails "migration" tools - ruby-on-rails

In ruby on rails normally use SQLite as a database.so a special property of rails called migration are work.but when we use "mongodb" as a database in rails.I see there have no migrate folder in the db directory.
Is there any way to use this migration property in rails when use mongodb.

According to the documentation here, db:migrate: Exists only for dependency purposes, but does not actually do anything.
However, because I am not sure of what version of rails you're using, how your project was setup and if you intend using just mongodb I will describe the process for both possibilities from scratch with all assumptions if any clearly stated.
This approach assumes you want to use mongodb alone
Create your Rails app with the --skip-active-record switch.
Remove sqlite3 from your Gemfile
add gem 'mongoid' to your Gemfile
and run bundle
Run rails g mongoid:config
Check your application.rb file and make sure that inside the 'class Application' you have this line Mongoid.load! './config/mongoid.yml' It's sometimes not included when the config is generated, but is needed to use Mongoid.
Mongoid is ready to go.
The Rails generators for model, scaffold, etc have been overridden by Mongoid. Any models, scaffolds etc that you create will create classes that include the Mongoid::Document module instead of inheriting from ApplicationRecord in the models folder.
For instance, when you run
rails g model person first_name last_name email_address
if you open up the file app/models/person.rb
You'd see
class Person
include Mongoid::Document
field :first_name, type: String
field :last_name, type: String
field :email_address, type: String
end

Related

Rails generate model including validations?

I was wondering if anybody knew of a way to do something like the following:
rails generate model Foo name:string, validates: {:name, uniqueness: true}
That is, whilst declaring a model generator with some attributes, work some rails magic to add your validations at the same time.
There isn't. The rails generate model command is directly tied to database functionality. For example, you should be able to do a command like this rails generate model Foo name:string:uniq. This would force the database to require a unique string for the name. This wouldn't add anything to your foo.rb file.
Here is some more information about rails model generations:
http://travisjeffery.com/b/2012/03/generate-rails-migrations-that-automagically-add-your-change/
As others have said, there isn't currently a way to do this. Most of the special options for the rails generate model command are parsed by the parse_type_and_options method in generated_attribute.rb. The model_generator.rb will then build the model and migration files using this info.
The template for the model file that is created is model.rb. In Rails 4 this template can add in special code for belongs_to, polymorphic, and has_secure_password but not code related to validations.
The template for the migration file that is created is create_table_migration.rb. In Rails 4 this can add in special options for limit, decimal, and precision.
Since Rails 3.2 it has been possible to pass :uniq to the column definition on the rails command line.
The way to do this is relatively simple; just add :uniq after the column and type definitions, e.g.:
rails generate model Foo name:string:uniq

Why rails is generating empty models?

I'm trying to generate some models but they are being generated without attributes.
I'm using a linux system and the rails version is:
rails --version
Rails 4.0.0
I've tried to generate the models using this commands:
rails g scaffold Bsdsd description:string test:string oaso:integer
and
rails g model Asdsd description:string test:string oaso:integer
The first results in this empty class model everything else ok:
class Bsdsd < ActiveRecord::Base
end
The second results in test files, migrations file(that contains the attributes) and this class model:
class Asdsd < ActiveRecord::Base
end
How can I correct this behavior?
Model attributes are inferred from database columns, so you don't need them specified in model classes.
In Rails 3.2 you had (if I remember correctly)
# attr_accessible :description, :test, :oaso
line generated. But protected attributes are deprecated in Rails 4.0 and replaced by strong parameters mechanism.
Nothing you're doing is wrong. But you're checking the wrong files. Look for CreateAsdsdsMigration (in the migrations directory) file and you'll see the auto-generated fields there
For those coming from Grails or Django, note that Rails creates the database FIRST-- not the other way around, where domainclass.groovy or models.py creates the database tables for you AFTER you define them. Look for yourapp/db/schema.rb and inside are all your classes and their field definitions.

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.

Why does "rails generate migration" call "invoke activerecord"

When running:
rails generate migration <someaction> field:type
I can see it is performing two actions:
Call invoke active_record
Create a migration file.
I understand perfectly why it is generating the migration file, but why does it invoke ActiveRecord? This bothers me because what if I want to create the migration file manually? how would I mimic this invocation (if it's even necessary..)?
The MigrationGenerator generator:
1) Loads your ORM (which by default in Rails is Active Record) to have it extend the correct 'ORM'::Migration class (again by default this is ActiveRecord::Migration)
2) It is itself an extension of the NamedBase generator which sees if your running Active Record to decide if it should pluralize the table names. This is so if you run
rails generate migration AddPartNumberToProducts part_number:string
or
rails generate migration AddPartNumberToProduct part_number:string
You get the same results in your file.
So the short answer is, you do not need to invoke active_record to create a migration by hand, but if you do and you are using Active Record make sure that your table names are pluralized in your migration file.
activerecord gem is invoked to generate the migration file.
If you look closely, the super class of a migration file is an ActiveRecord::Migration class.

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.

Resources