how to set default value to column in rails while creating migration - ruby-on-rails-3

I am new to Model in rails. I know how to create model & how to add column to them. Now I want to set default value to a column but I am not getting that how exactly I can do it.
I generated new model
rails g model User
then added column to it
rails generate migration AddNotificationEmailToUsers notification_email:boolean
Now I want to set value of Notification column default as true.
Please guide me how to write the migration for the same. Thank you!!!

You can't do this from the command line - you'll have to edit the migration file and change the corresponding line to something like
add_column :users, :notification_email, :boolean, :default => true

Best approach here is to use change_column in your migration. It is advertised to change type but you can use it to attach a default to existing column.
I had
location :integer
in schema and I wanted to default to zero, so I wrote a migration as such:
change_column :player_states, :location, :integer, :default => 0
That did the trick.

Frederick Cheung is correct you will need to edit the migration file for this.
Just a minor update add comma after the data type before specifying the default value.
add_column :users, :notification_email, :boolean, :default => true

As of now there is no way around to specify default value defined through terminal in rails migration.
you can execute below steps in order to specify default value for a column
1). Execute
$ rails generate migration AddNotificationEmailToUsers notification_email:boolean
2). Specify the new column default value to TRUE/FALSE by editing the new migration file created.
class AddNotificationEmailToUsers < ActiveRecord::Migration
def change
add_column :users, :notification_email, :boolean, default: true
end
end
3).Run above generated migration by Executing.
$ rake db:migrate

Related

What does "null: false" really do?

I recently created a rails migration to add a Username to my devise Users.
add_column :users, :username, :string
I created a test account and signed up without entering a username. The registration went through and created a user with no user name. I had to fix this since I need a username to set the profile url. So I updated my migration to:
add_column :users, :username, :string, null: false
I thought this would prevent a user from creating a account with a null username - didn't work! I was still about to register with no username.
Eventually adding...
validates_presence_of :username
...to my user.rb model fixed the issue. But why didn't null:false stop it? Why should I keep it and how does it work?
This statement:
add_column :users, :username, :string, null: false
translates exactly to SQL DDL (Data Definition Language) standard:
ALTER TABLE users ADD username VARCHAR(255) NOT NULL;
The trailing NOT NULL is effect of null: false. You can use other column modifiers which some of them are directly translated into DDL.
Remember that if you already apply the migration to the database the further modifications should be done with a new migration file. Updates to migration Ruby files are not propagated to database schema when the migration was already applied. Eventually you can rollback last migrations and rerun them but then you may loose existing data during the schema rollback. See Changing Existing Migrations

RoR: how can I add columns to my database on my live heroku app?

I am trying to add :price, :location, and :product to the columns for my microposts table. I have already done a bunch of other migrations and I have heard that rolling back all of migrations and redoing them is error prone. So I guess the other option is the schema file? I have heard that the schema file is just to be read and not edited. I have been looking at http://guides.rubyonrails.org/migrations.html but can't find the right info. They briefly talk about change_table which I think could be useful but it doesn't go into depth. Is this what I am looking for?
Just create a new standalone migration:
rails g migration add_price_location_and_product_to_microposts
It will create a file in the db/migrate folder, edit it:
def change
add_column :microposts, :price, :float # dont forget to change the type to the columns
add_column :microposts, :location, :string
add_column :microposts, :product, :integer
end
(You can define the change method, instead of up and down because add_column is a reversible command.)
And then, run rake db:migrate

Default value not populating in migration with Rails and Postgresql

I am currently trying to run this migration:
class AddDroppedProjectsCountToUser < ActiveRecord::Migration
def self.up
add_column :users, :dropped_projects, :integer, {:default=>0, :required=>true}
end
def self.down
remove_column :users, :dropped_projects
end
end
The column is added correctly, but none of the old records are populated with 0. They are nil. I have tried using default=>'0' as well, to no avail. Any idea why this might be happening? (Rails 3.0.3)
Edited to add: When I create a new user it works fine, and everything looks correct. It's just the old users that still have nil for that value in the table.
What happens if you say:
def self.up
add_column :users, :dropped_projects, :integer, :null => false, :default => 0
end
instead? Without the :null=>false you're still allowing NULL in dropped_projects so there's no reason for PostgreSQL to make them 0. Also, I don't think :required is a valid option for add_column; since the options are just a simple Hash and add_column only looks for options it knows about, your stray :required option is silently ignored.
you could do this:
(taken from http://apidock.com/rails/ActiveRecord/Migration)
Using a model after changing its table
Sometimes you’ll want to add a column in a migration and populate it
immediately after. In that case, you’ll need to make a call to
Base#reset_column_information in order to ensure that the model has
the latest column data from after the new column was added. Example:
class AddPeopleSalary < ActiveRecord::Migration
def up
add_column :people, :salary, :integer
Person.reset_column_information
Person.all.each do |p|
p.update_column :salary, SalaryCalculator.compute(p)
end
end
end
I believe this is due to the fact that you are changing the old migration, instead of creating a new.
In this case, the solution is to check the schema file (schema.rb). It does not change automatically, and add
t.integer "dropped_projects", default: 0, null: false

Adding a column to an existing table in a Rails migration

I have a Users model which needs an :email column (I forgot to add that column during the initial scaffold).
I opened the migration file and added t.string :email, did rake db:migrate, and got a NoMethodError. Then I added the line
add_column :users, :email, :string
again rake db:migrate, again NoMethodError. Am I missing a step here?
Edit: here's the migration file.
class CreateUsers < ActiveRecord::Migration
def self.up
add_column :users, :email, :string
create_table :users do |t|
t.string :username
t.string :email
t.string :crypted_password
t.string :password_salt
t.string :persistence_token
t.timestamps
end
end
def self.down
drop_table :users
end
end
If you have already run your original migration (before editing it), then you need to generate a new migration (rails generate migration add_email_to_users email:string will do the trick).
It will create a migration file containing line:
add_column :users, email, string
Then do a rake db:migrate and it'll run the new migration, creating the new column.
If you have not yet run the original migration you can just edit it, like you're trying to do. Your migration code is almost perfect: you just need to remove the add_column line completely (that code is trying to add a column to a table, before the table has been created, and your table creation code has already been updated to include a t.string :email anyway).
Use this command on the terminal:
rails generate migration add_fieldname_to_tablename fieldname:string
and
rake db:migrate
to run this migration
Sometimes rails generate migration add_email_to_users email:string produces a migration like this
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
end
end
In that case you have to manually an add_column to change:
class AddEmailToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :email, :string
end
end
And then run rake db:migrate
You can also do
rake db:rollback
if you have not added any data to the tables.Then edit the migration file by adding the email column to it and then call
rake db:migrate
This will work if you have rails 3.1 onwards installed in your system.
Much simpler way of doing it is change let the change in migration file be as it is.
use
$rake db:migrate:redo
This will roll back the last migration and migrate it again.
To add a column I just had to follow these steps :
rails generate migration add_fieldname_to_tablename fieldname:string
Alternative
rails generate migration addFieldnameToTablename
Once the migration is generated, then edit the migration and define all the attributes you want that column added to have.
Note: Table names in Rails are always plural (to match DB conventions). Example using one of the steps mentioned previously-
rails generate migration addEmailToUsers
rake db:migrate
Or
You can change the schema in from db/schema.rb, Add the columns you want in the SQL query.
Run this command: rake db:schema:load
Warning/Note
Bear in mind that, running rake db:schema:load automatically wipes all data in your tables.
You can also add column to a specific position using before column or after column like:
rails generate migration add_dob_to_customer dob:date
The migration file will generate the following code except after: :email. you need to add after: :email or before: :email
class AddDobToCustomer < ActiveRecord::Migration[5.2]
def change
add_column :customers, :dob, :date, after: :email
end
end
You also can use special change_table method in the migration for adding new columns:
change_table(:users) do |t|
t.column :email, :string
end
When I've done this, rather than fiddling the original migration, I create a new one with just the add column in the up section and a drop column in the down section.
You can change the original and rerun it if you migrate down between, but in this case I think that's made a migration that won't work properly.
As currently posted, you're adding the column and then creating the table.
If you change the order it might work. Or, as you're modifying an existing migration, just add it to the create table instead of doing a separate add column.
You can also do this ..
rails g migration add_column_to_users email:string
then rake db:migrate
also add :email attribute in your user controller ;
for more detail check out http://guides.rubyonrails.org/active_record_migrations.html
You can also force to table columns in table using force: true, if you table is already exist.
example:
ActiveRecord::Schema.define(version: 20080906171750) do
create_table "authors", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
end
You could rollback the last migration by
rake db:rollback STEP=1
or rollback this specific migration by
rake db:migrate:down VERSION=<YYYYMMDDHHMMSS>
and edit the file, then run rake db:mirgate again.

model missing required attr_accessor for 'photo_file_name' when uploading with paperclip and S3 on heroku

Setting up paperclip with S3 in my linux dev environment was a snap -- everything works out of the box. However, I can't get it to work on Heroku.
When I try to do an upload, the log shows:
Processing ItemsController#create (for 72.177.97.9 at 2010-08-26 16:35:14) [POST]
Parameters: {"commit"=>"Create", "authenticity_token"=>"0Hy3qvQBHE1gvFVaq32HMy2ZIopelV0BHbrSeHkO1Qw=", "item"=>{"photo"=>#<File:/home/slugs/270862_4aa601b_4b6f/mnt/tmp/RackMultipart20100826-6286-1256pvc-0>, "price"=>"342", "name"=>"a new item", "description"=>"a new item", "sold"=>"0"}}
Paperclip::PaperclipError (Item model missing required attr_accessor for 'photo_file_name'):
I found one blog post that referenced this error, and it said to add this to my model:
attr_accessor :photo_file_name
attr_accessor :photo_content_type
attr_accessor :photo_file_size
attr_accessor :photo_updated_at
That does indeed make the model missing required attr_accessor for 'photo_file_name' error go away, but it still doesn't work. See my other question for details. As I have figured out that with the attr_accessor lines added to my model the uploads fail even on my dev system, I suspect that is not the right answer.
Found the problem: needed to update the database.
heroku run rake:db:migrate
heroku restart
I had done what I thought would have accomplished the same thing already:
heroku rake db:schema:load
but perhaps that doesn't work or something went wrong in the process.
Error like this occurs if you create wrong column type in migration. When you define new table migration for paperclip, you need to specify t.attachment :name insted of t.string :name. Or add_attachment :table, :name when you add new paperclip column in existed table. And now you don't need to add these attributes in attr_accessor in model.
Well, this message seems to be because the columns it's missing. Try create a migration creating the columns:
class AddPhotoToEvent < ActiveRecord::Migration
def change
add_column :events, :photo_file_name, :string
add_column :events, :photo_content_type, :string
add_column :events, :photo_file_size, :integer
add_column :events, :photo_updated_at, :datetime
end
end
This work for me, here i have a table events with photo