Rails 3 migration - ruby-on-rails

Current migration:
t.string "email", :default => "", :null => false
add_index :users, :email, :unique => true
I want to create a new migration to remove the :null => false requirement and also remove the default => "" for email. Also, I would like to change the index to remove :unique => true. What's the syntax?

I haven't done much with indices, and there doesn't seem to be a change_index method on ActiveRecord::Migration, but you can try something like this:
class ChangeUserStuff < ActiveRecord::Migration
def self.up
change_column :users, :email, :default => "", :null => true
remove_index :users, :column => :email
add_index :users, :email
end
def self.down
change_column :users, :email, :default => "", :null => false
remove_index :users, :column => :email
add_index :users, :email, :unique => true
end
end
There was some funny behavior regarding changing :null options, but I believe setting them to true instead of omitting should handle it.

Related

Undefined method `to_sym' for {:null=>false} in my migration: why?

I have a migration that give me an error:
class DeviseTokenAuthCreateUsers < ActiveRecord::Migration
def change
unless column_exists? :users, :provider
add_column :users, :provider, :null => false
end
unless column_exists? :users, :uid
add_column :users, :uid, :null => false, :default => "email"
end
unless column_exists? :users, :tokens
add_column :users, :tokens, :text
end
User.reset_column_information
User.all.each{|u| u.save! }
add_index :users, [:uid, :provider], :unique => true
end
end
The error is:
undefined method `to_sym' for {:null=>false}:Hash/Users/scrivoaroby/.rvm/gems/ruby-2.0.0-p481/gems/activerecord-4.1.9/lib/active_record/connection_adapters/abstract/schema_definitions.rb:311:in `add_column'
My rails version is 4.1.9
Any idea?
The third argument for add_column should be the datatype. Instead of something like:
add_column :users, :provider, :null => false
You'll want something like this, with whatever datatype is appropriate for your columns:
add_column :users, :provider, :string, :null => false
This will also need to be done for the :uid column.

Database not completely updated in rails migration

I am new to Ruby on Rails. I have a migration called create user
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.column :username, :string, :limit => 25, :default => "", :null => false
t.column :hashed_password, :string, :limit => 40, :default => "", :null => false
t.column :first_name, :string, :limit => 25, :default => "", :null => false
t.column :last_name, :string, :limit => 40, :default => "", :null => false
t.column :email, :string, :limit => 50, :default => "", :null => false
t.column :display_name, :string, :limit => 25, :default => "", :null => false
t.column :user_level, :integer, :limit => 3, :default => 0, :null => false
end
User.create(:username=>'test',:hashed_password=>'test',:first_name=>'test',:last_name=>'test',:email=>'test#test.com',:display_name=> 'test',:user_level=>9)
end
end
When I run rake db:migrate the table is created with the columns as mentioned above but the test data are not there
mysql>select * from users;
Empty set (0.00 sec)
EDIT I just dropped the whole database and restarted the migration and now it is showing the following error.
rake aborted!
An error has occurred, all later migrations canceled:
Can't mass-assign protected attributes: username, hashed_password, first_name, last_name, email, display_name, user_level
What am I doing wrong please help?
Thank you.
add
attr_accessible :username, :hashed_password, :first_name, :last_name, :email, :display_name, :user_level
to your user.rb
That's Rails way of prohibiting users to create or update objects via a param hash. You need to specify your User attributes as attr_accessible in your model:
example :
class User
attr_accessible :username, :firstname (etc)
end
Read more about Mass Assignment here.
just to complete the answer about testing environment. You can run rake db:test:prepare to check the migrations and load schema !

add column to mailboxer migration

I wanted to add two columns to the migration that makes the notifications for the mailboxer gem. When I place both in the migration that creates the notification and then run a migration it goes through. I then input them into the form and when I submit them there are no errors and the log shows that its take them. For some reason when I try to display them they don't show up, the only thing that is showing is the original things that were part of the migration which is subject and body. My question is how can I add columns to this migration?
Here is the migration with my two columns of lat and long added to the notifications section.
# This migration comes from mailboxer_engine (originally 20110511145103)
class CreateMailboxer < ActiveRecord::Migration
def self.up
#Tables
#Conversations
create_table :conversations do |t|
t.column :subject, :string, :default => ""
t.column :created_at, :datetime, :null => false
t.column :updated_at, :datetime, :null => false
end
#Receipts
create_table :receipts do |t|
t.references :receiver, :polymorphic => true
t.column :notification_id, :integer, :null => false
t.column :read, :boolean, :default => false
t.column :trashed, :boolean, :default => false
t.column :deleted, :boolean, :default => false
t.column :mailbox_type, :string, :limit => 25
t.column :created_at, :datetime, :null => false
t.column :updated_at, :datetime, :null => false
end
#Notifications and Messages
create_table :notifications do |t|
t.column :type, :string
t.column :body, :text
t.column :subject, :string, :default => ""
t.column :lat, :text
t.column :long, :text
t.references :sender, :polymorphic => true
t.references :object, :polymorphic => true
t.column :conversation_id, :integer
t.column :draft, :boolean, :default => false
t.column :updated_at, :datetime, :null => false
t.column :created_at, :datetime, :null => false
end
#Indexes
#Conversations
#Receipts
add_index "receipts","notification_id"
#Messages
add_index "notifications","conversation_id"
#Foreign keys
#Conversations
#Receipts
add_foreign_key "receipts", "notifications", :name => "receipts_on_notification_id"
#Messages
add_foreign_key "notifications", "conversations", :name => "notifications_on_conversation_id"
end
def self.down
#Tables
remove_foreign_key "receipts", :name => "receipts_on_notification_id"
remove_foreign_key "notifications", :name => "notifications_on_conversation_id"
#Indexes
drop_table :receipts
drop_table :conversations
drop_table :notifications
end
end
My show view looks like
%h1= conversation.subject
%ul
= content_tag_for(:li, conversation.receipts_for(current_user)) do |receipt|
- message = receipt.message
%h3= message.subject
%p= message.body
%p= message.lat
%p= message.long
= render 'messages/form', conversation: conversation
This is what comes up in the console, for lat and long you see it says null
Notification Load (0.1ms) SELECT "notifications".* FROM "notifications" ORDER BY "notifications"."id" DESC LIMIT 1
--- !ruby/object:Message
attributes:
id: 4
type: Message
body: game
subject: wiz
lat: !!null
long: !!null
sender_id: 1
sender_type: User
conversation_id: 2
draft: false
updated_at: 2013-03-10 04:37:54.984277000Z
created_at: 2013-03-10 04:37:54.984277000Z
notified_object_id: !!null
notified_object_type: !!null
notification_code: !!null
attachment: !!null
=> nil
I am not sure I understand exactly what you are doing, but it sounds like possibly you haven't added the two new columns to attr_accessible and they aren't being saved because of that. That's the first thing I would check (it's in the model).
Otherwise, go to the console and see if your new columns are there and see if there is data in them. That will help you find where the problem is.

rake db:migrate error wrong number of arguments (5 for 4)

This is my migration file:
class AddSeoMetaInfoToArticles < ActiveRecord::Migration
def self.up
add_column :articles, :seo_title, :string, { :default => "", :null => false }
add_column :articles, :seo_description, :string, { :default => "", :null => false }
add_column :articles, :seo_keywords, :string, :string, { :default => "", :null => false }
end
def self.down
remove_column :articles, :seo_keywords
remove_column :articles, :seo_description
remove_column :articles, :seo_title
end
end
When I try to run 'rake db:migrate' I get the following error
$ rake db:migrate
AddSeoMetaInfoToArticles: migrating =======================================
-- add_column(:articles, :seo_title, :string, {:default=>"", :null=>false})
-> 0.0341s
-- add_column(:articles, :seo_description, :string, {:default=>"", :null=>false})
-> 0.0100s
-- add_column(:articles, :seo_keywords, :string, :string, {:default=>"", :null=>false})
rake aborted!
An error has occurred, this and all later migrations canceled:
wrong number of arguments (5 for 4)
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
I'm relatively new to rails and I'm not sure what I'm doing wrong. This is Rails 3.0.9, and a Postgres db if that makes a difference.
add_column :articles, :seo_keywords, :string, :string, { :default => "", :null => false }
has :string twice, so you end up with 5 arguments being passed instead of 4.
You might also want to consider writing you migration with change - your migration is equivalent to
class AddSeoMetaInfoToArticles < ActiveRecord::Migration
def change
change_table :articles do |t|
t.string :seo_title, :default => "", :null => false
t.string :seo_description, :default => "", :null => false
t.string :seo_keywords, :default => "", :null => false
end
end
end
which I find easier on the eye. It also has the advantage that you can pass :bulk => true to change_table which will combine all 3 column additions into 1 alter table statement, which is usually much faster.
Both ways will of course work.
You give the :string argument twice in this line:
add_column :articles, :seo_keywords, :string, :string, { :default => "", :null => false }

Ruby on Rails + devise: How can i create customize users table with devis rake db:migrate?

rails generate devise User I got this=>
class DeviseCreateUsers < ActiveRecord::Migration
def self.up
create_table(:users) do |t|
t.database_authenticatable :null => false
t.recoverable
t.rememberable
t.trackable
# t.encryptable
# t.confirmable
# t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both
# t.token_authenticatable
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
def self.down
drop_table :users
end
end
But i want to create a users table with username, email, password, role, group, mark, created_at, modified_at columns.
How can i do this ?
Is this structure correct to have username, password, email, group, role, mark ?
class DeviseCreateUsers < ActiveRecord::Migration
def self.up
create_table(:users) do |t|
t.database_authenticatable :null => false
t.recoverable
t.rememberable
t.trackable
# t.encryptable
# t.confirmable
# t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both
# t.token_authenticatable
t.string :username
t.string :password
t.string :email
t.string :group
t.string :role
t.integer :mark
t.timestamps
end
add_index :users, :email, :unique => true
add_index :users, :reset_password_token, :unique => true
# add_index :users, :confirmation_token, :unique => true
# add_index :users, :unlock_token, :unique => true
# add_index :users, :authentication_token, :unique => true
end
def self.down
drop_table :users
end
end
What are these?
t.database_authenticatable :null => false
t.recoverable
t.rememberable
t.trackable
You can perform a migration to add some fields to the user table.
For example:
rails g add_fields_to_users username:string # as well as other fields you need
Then, in order to add columns to your table run:
rake db:migrate
Devise has already generated some columns you need like: email, password, created_at, updated_at...
For adding roles to your user model you should watch the cancan screencast: railscasts and also read the doc in order to see some updates.
EDIT:
If you want to add fields manually you could add them in your self.up method before running your migration:
def self.up
create_table(:users) do |t|
#...
t.rememberable
t.trackable
t.string :username
#... your other attributes here
end

Resources