How to check if a colum is present in table in rails migration - ruby-on-rails-5

currently rails version 5.
In it I want to write the migration in condition that migration should run only when the field does not exist in the database for a particular table.
Please suggest how to implement it in rails, Thanks in advance.

def self.up
unless ActiveRecord::Base.connection.column_exists?(:table_name, :column_name)
add_column :table_name, :column_name, :data_type
end
end

Related

Multicolumn index with expression (PostgreSQL and Rails)

I need to create multicolumn index for 3 columns (VARCHAR, INT and INT), lets call them varchar_col, int1_col and int2_col. For VARCHAR column I need to apply lower(varchar_col) expression.
When I create one-column index with expression
add_index :table, 'lower(varchar_col)', name: 'index_name'
it works, but when I try to create multicolumn with
add_index :table, ['lower(varchar_col)', :int1_col, :int2_col], name: 'index_name'
I receive
PG::UndefinedColumn: ERROR: column "lower(varchar_col)" does not exist
Is it possible to create such an index with Rails add_index function or I need to execute SQL query in migration file? Does PostgreSQL support multicolumn index with expression? And if it supports, what I have to write in migration file to make it works?
Thank you for any help!
P.S. I'm using Rails 5.
You may send the columns with the expressions as a string:
add_index :table, 'lower(varchar_col), int1_col, int2_col', name: 'index_name'
So, after a little research, I've made it with executing SQL query in migration file. I just leave it here as another approach, but Ilya Lavrov's suggestion with string of columns also works.
migration file:
def up
connection.execute(%q{
CREATE INDEX index_name ON table(lower(varchar_col), int1_col, int2_col)
})
end
def down
remove_index :table, name: 'index_name'
end

Ruby on rails - Migrate date field in database into 3 integer fields using migration

I'm new to RoR, and need some help on migration.
I have an existing database containing a "date" column in a mysql database.
I need to store them into 3 separate integer fields (year, month, date) (don't ask me why, because my clients are idiots)... and need to migrate the existing column into the new columns (The existing database already contain data). I'm just wondering how could I do that in migration?
Thank you
After some digging... solved it.
Migration is not the preferred way of doing this, rake task should be used.
First, generate the new columns using migrations, than add the new attr_accessible in the model.
To generate a rake task, follow http://railsguides.net/how-to-generate-rake-task/ link.
And use the following code, assuming the model containing the date column is called Visit
namespace :visit_date_migration do
desc "Migrate visit date into 3 integer columns for year/month/date"
task :migrate_date => :environment do
Visit.all.each do |visit|
unless visit.visit_date.nil? || visit.visit_date == 0
year = visit.visit_date.year
month = visit.visit_date.month
day = visit.visit_date.day
visit.visit_date_year=year
visit.visit_date_month=month
visit.visit_date_date=day
visit.save!
end
end
end
end
And run the rake task like a normal task.

How can I import a SQL file into a Rails database?

I've got a .sql file that I'd like to load into my Rails database using a Rake task. How can I do this?
The easiest way:
bundle exec rails db < $SQL_FILE
example:
bundle exec rails db < my_db.sql
The Easy Way
This works for simple cases.
ActiveRecord::Base.connection.execute(IO.read("path/to/file"))
Solution found on the Ruby On Rails mailing list from 2006 (but still works in 2011 on Rails 3.1).
Footnotes
This related question implied this solution, but rejected it for big imports. I wanted to show it explicitly, since it works for smaller ones.
The file I was trying to import contained a LOCK TABLES followed by an insert. The data was for a MySQL database. Mysql2 said it had an invalid SQL syntax error until I removed the lock and unlock statements.
On MySQL this gave me a syntax error. Splitting the sql into statements made it work.
sql = File.read(sql_file)
statements = sql.split(/;$/)
statements.pop # remove empty line
ActiveRecord::Base.transaction do
statements.each do |statement|
connection.execute(statement)
end
end

Does Rails recognize db view?

Is there a way that to access my db view as a table for a model?
Yes, you can use views just fine, they behave just like tables in ActiveRecord. I don't know what database you're using, but I use them in Oracle and haven't had a problem.
The only difference is that if you want to have your migrations automatically create them, you'll have to forego the typical create_table and instead execute SQL statements to create it.
With MongoDb, I accessed to the MongoDB Views with the following method.
Firstly you should create a dummy model to be able to use MongoDB connectors. You can manually create new file with the name view_names.rb and append below lines.
class ViewName
include Mongoid::Document
include Mongoid::Timestamps
end
And then to access records;
ViewName.collection.find({})
>> #<Mongo::Collection::View:0x0000000107cd4378>)
find gets MongoDB queries as parameter, so you can pass your logic as hash to find method.
{created_at: { '$lte': Date.todat - 2.week }}
View name on MongoDB should be plural view_names just as same with the others.

want to change columntype in a table through migration

Hi i have a table in which there are two columns from and to of type datatime i want to change the datatype from datetime to date. i dont know the exact command for chagning column type in migrations like rails g
From the command line, run:
rails generate migration change_data_type_for_table_column
Write your migration as:
change_table :table do |t|
t.change :column, :type
end
Use change_column.
change_column(:table, :column, :date)