I'm getting this weird error: undefined method 'add_column' for #<Class:0x007f7a6a73cf30> (NoMethodError) when I try to run rails s in heroku. It seems to be throwing this error in the following migration:
class AddPresentationAttributesToPosts < ActiveRecord::Base
add_column :presentations, :ticker, :string
add_column :presentations, :action, :string
add_column :presentations, :thesis, :string
add_column :presentations, :slideshare_url, :string
end
However, all of this works locally and heroku run rake db:migrate also works without throwing an error. Any idea what this could be?
If you want to write a migration, you should inherit from the ActiveRecord::Migration. And don't forget about up, down and change method:
class AddPresentationAttributesToPosts < ActiveRecord::Migration
def change
add_column :presentations, :ticker, :string
add_column :presentations, :action, :string
add_column :presentations, :thesis, :string
add_column :presentations, :slideshare_url, :string
end
end
Related
I am newbie with rails and here is my problem.
I created a very simple rails program and in the db > migrate > 2023.._add_columns_to_user.rb file, I added this code to this file
class AddColumnsToUser < ActiveRecord::Migration[7.0]
def change
add_column :users, :full_name, :string
add_column :users, :from, :string
add_column :users, :about, :text
add_column :users, :language, :string
add_column :users, :status, :boolean
add_column :users, :status, :boolean, default: false
end
end
Then I ran this code
rails db:migrate
But it gave me this error
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "users" does not exist
May be I must create the database first?
Could you please give me some advices for this problem?
Here is all of my code, if you need for reference.
https://github.com/nguyencuc2586/Addcustomfieldsoutusermodel
Thank you in advance.
You can't alter a table that hasn't yet been created. Your migration should be wrapped in a table defintion:
class CreateUsers < ActiveRecord::Migration[7.0]
def change
create_table :users do |t|
t.string :full_name # shorthand for add_column :users, :full_name, :string
t.string :from
t.text :about
t.boolean :status, default: false # why on earth is this a boolean?
t.timestamps
end
end
end
This results in CREATE TABLE users (...) while your migration would result in ALTER TABLE users (...).
Is there any better way to add new columns to rails table than this way
class AddColumnsToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :first_name, :string
add_column :users, :last_name, :string
add_column :users, :contact1, :integer
add_column :users, :contact2, :integer
add_column :users, :contact3, :decimal
add_column :users, :contact4, :integer
add_column :users, :contact5, :integer
add_column :users, :contact6, :string
add_column :users, :contact7, :integer
add_column :users, :contact8, :integer
add_column :users, :contact9, :integer
end
end
Can we use change_table method and write these inside a block? instead of repeating the add_column again and again
You can add multiple columns to a same table like this
def change
change_table :users do |t|
t.string :first_name
t.string :last_name
end
end
If you just want to dry, then you can write in following manner also,
{
string: [:first_name, :last_name, :contact6],
integer: [:contact1 ,:contact2 ,:contact4 ,:contact5 ,:contact7 ,:contact8 ,:contact9],
decimal: [:contact3]
}.each do |type, columns|
columns.each { |col| add_column :users, col, type }
end
I had named the add_column :users, :confirmed_at(confirmation_at), :datetime by accident. So I changed it to the appropriate field name :(confirmed_at)
then I entered : rake db:rollback in command line. it was aborted for some reason with the message below however first my Rails db migrate file code:
class AddConfirmableToDevise < ActiveRecord::Migration
def up
add_column :users, :confirmation_token, :string
add_column :users, :confirmed_at, :datetime
add_column :users, :confirmation_sent_at, :datetime
add_index :users, :confirmation_token, unique: true
end
def down
remove_column :users, :confirmation_token, :confirmed_at, :confirmation_sent_at
end
end
Error after migration:
tzurch:~/workspace (gravitar) $ rake db:migrate:redo
#the error that came up below
_________________________________________________
== 20160902201448 AddFullnameToUser: reverting ================================
-- remove_column(:users, :fullname, :string)
-> 0.0207s
== 20160902201448 AddFullnameToUser: reverted (0.0284s) =======================
== 20160902201448 AddFullnameToUser: migrating ================================
-- add_column(:users, :fullname, :string)
-> 0.0008s
== 20160902201448 AddFullnameToUser: migrated (0.0009s) =======================
== 20160913221959 AddConfirmableToDevise: migrating ===========================
-- add_column(:users, :confirmation_token, :string)
-> 0.0009s
-- add_column(:users, :confirmed_at, :datetime)
-> 0.0005s
-- add_column(:users, :confirmation_sent_at, :datetime)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
SQLite3::SQLException: duplicate column name: confirmation_sent_at: ALTER TABLE "users" ADD "confirmation_sent_at" datetime:
The problem here is the syntax you are using to remove column is wrong.
Correct syntax is remove_column
remove_column(table_name, column_name, type = nil, options = {})
Change down migration with
class AddConfirmableToDevise < ActiveRecord::Migration
def up
add_column :users, :confirmation_token, :string
add_column :users, :confirmed_at, :datetime
add_column :users, :confirmation_sent_at, :datetime
add_index :users, :confirmation_token, unique: true
end
def down
remove_column :users, :confirmation_token
remove_column :users, :confirmed_at
remove_column :users, :confirmation_sent_at
remove_index :users, :confirmation_token
end
end
Or remove the down migration altogether and replace up with change, rails will figure out how to rollback:
class AddConfirmableToDevise < ActiveRecord::Migration
def change
add_column :users, :confirmation_token, :string
add_column :users, :confirmed_at, :datetime
add_column :users, :confirmation_sent_at, :datetime
add_index :users, :confirmation_token, unique: true
end
end
I suppose you have already have confirmation_sent_at field in this table in db
I have a devise Users Model
class DeviseCreateUsers < ActiveRecord::Migration
def change
...
end
end
I want to add these columns to the model. I think I might be confusing myself with the automatic pluralize that Rails does.
When I use the command rails g migration AddDetailsToUsers and I added following code inside the change method.
class AddDetailsToUsers < ActiveRecord::Migration
def change
add_column :Users, :username, :string
add_column :Users, :firstname, :string
add_column :Users, :lastname, :string
add_column :Users, :billing_address, :string
add_column :Users, :credit_card, :string
add_column :Users, :total_earned, :string
add_column :Users, :home_address, :string
add_column :Users, :leeway_time, :string
end
ends
I did rake db:migrate to try to update the DB, I get
== 20141012065730 AddDetailsToUsers: migrating ================================
-- add_column(:Users, :username, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "Users" does not exist
I try to see if I can play with this table in `rails c
User.first
User Load (0.9ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> nil
Table name is case sensitive. Change all occurrences of :Users to :users in the migration file
eg:
add_column :users, :username, :string
add_column :users, :firstname, :string
..
This may not be Devise specific but I'm wondering how to add an additional module to a gem that has already been installed when the initial install didn't include said module? In the case of Devise the migration helper t.confirmable is useful in the initial migration's Self.up method and the whole User table is torn down in the Self.down. My Rails-fu isn't strong enough to uncover what the t.confirmable helper is actually doing...
What happens when the User table already exists and you want to add something like :confirmable or :token_authenticatable? Obviously you can't just create_table(:users) again... so me thinks I want to add_column :users, ... and remove_column :users, ... but how do we go about finding out what needs to happen?
Take a look at Devise::Schema
https://github.com/plataformatec/devise/blob/master/lib/devise/schema.rb
which has this
# Creates confirmation_token, confirmed_at and confirmation_sent_at.
def confirmable
apply_devise_schema :confirmation_token, String
apply_devise_schema :confirmed_at, DateTime
apply_devise_schema :confirmation_sent_at, DateTime
end
and then
https://github.com/plataformatec/devise/blob/master/lib/devise/orm/active_record.rb
def apply_devise_schema(name, type, options={})
column name, type.to_s.downcase.to_sym, options
end
So in your migration just do
add_column :users, :confirmation_token, :string
add_column :users, :confirmed_at, :datetime
add_column :users, :confirmation_sent_at, :datetime
and the opposite for the down..
Your migration:
class DeviseAddConfirmable < ActiveRecord::Migration
def change
change_table(:users) do |t|
t.confirmable
end
add_index :users, :confirmation_token, :unique => true
end
end