DangerousAttributeError in OmniAuth create is defined by ActiveRecord - ruby-on-rails

Please see this page, as I have the same problem: DangerousAttributeError in OmniAuth Railscast Tutorial: create is defined by ActiveRecord
However being fairly new to rails, I am not quite sure as to how to remove the fields they speak of from the database. In other-words, there is no step-by-step concise way described anywhere in that post.
The below post is in fact a proper solution, but it is unclear as to what he was referring to when he wrote: "rails g migration remove_silly_authentication_fields_which_should_not_be_there" Not sure what "silly_authentication_fields_which_should_not_be_there" is exactly.
Here is the post I am referring to:
So just to finish the question off you will need to create a migration
using this command:
rails g migration
remove_silly_authentication_fields_which_should_not_be_there
Which looks something like this:
class DropSillyControllerAttributes < ActiveRecord::Migration def
change
remove_column :authentications, :index
remove_column :authentications, :create
remove_column :authentications, :destroy end end
And run it using the usual:
rake db:migration
Or alternatively you should be able to run:
rake db:rollback
To roll back the changes just made to the database and:
rails d scaffold authentication
To remove all the files, then run:
rails g scaffold authentication user_id:integer provider:string
uid:string
And do the other stuff manually
I did exactly the same thing myself by the way.

it's telling you to create a migration to remove the problematic fields and then run the migration
to make it clearer:
run this command:
rails g migration drop_silly_controller_attributes
that command will create a file in /db/migratie/ with the timestamp and that name, something like:
2013121212312312_drop_silly_controller_attributes.rb
open that file and modify it to look like this:
class DropSillyControllerAttributes < ActiveRecord::Migration
def change
remove_column :authentications, :index
remove_column :authentications, :create
remove_column :authentications, :destroy
end
end
then you can run the migration doing:
rake db:migrate
it's confusing because the if you generate the migration with "remove_silly_authentication_fields_which_should_not_be_there" the class should be RemoveSillyAuthenticationFieldsWhichShouldNotBeThere, but then it says "DropSillyControllerAttributes", so you should generate the migration with drop_silly_controller_attributes to make it consistence

Related

rails migration is not reflecting while migration is successful

I have created 2 tables (categories and products) and I did has_many association like Category has_many :products and Product belongs_to :category.
When I do a migration like:
rails generate migration add_product_id_to_categories product_id:integer
then migration is running but not seeing product_id in Category.
I've tried multiple ways like
add_product_id_to_category product_id:integer
but still facing the same problem.
You only generated a migration file (rails generate migration add_product_id_to_categories product_id:integer). You have to run the migration with rake db:migrate.
Generating a migration is a different thing than actually running it. You just generated it, and in order to execute what you have written, you need to run it, and you can do so by invoking the following command:
rake db:migrate
Not sure that either you have run the migration or not, run the following command, and it will tell you the statues of all the migrations. If the status is up, the migration has been run, and for down, a migration couldn't be run.
rake db:migrate:status
When you run a migration, and you would like to get notified in terminal that it has been successfully run, you can add a puts statement in there like following:
class AddColumnToCategories < ActiveRecord::Migration
def change
add_column :categories, :product_id, :integer, index: true
puts "product_id column has been added into categories."
end
end
Have you tried rails generate migration AddProductIdToCategories product_id:integer?
When you have created the migration if you look inside the migration file you can see if any code has been generated in the change method before you run the migration. If it has not generated any content you can manually add it:
def change
add_column :categories, :product_id, :integer
end

Adding a column through the terminal

How do you add a column to a table using ActiveRecord through the terminal. I am trying to use add_column method but its not working. Any ideas please?
It is better to write a migration and a must if you are working with a team. When you make db changes, then every developer's environment has to be updated also. Otherwise, you will have some mad developers at you.
rails generate migration AddPartNumberToProducts part_number:string
will generate
class AddPartNumberToProducts < ActiveRecord::Migration
def change
add_column :products, :part_number, :string
end
end
Then you run the migration
rake db:migrate
http://guides.rubyonrails.org/migrations.html
Edit:
For a rails console command line check #tadman's answer or use what Bengala proposed like
ActiveRecord::Migration.add_column :products, :part_number, :string
You can run migrations directly in rails console rails c with ActiveRecord::Migration
For your purpose the next command will do what you ask:
> ActiveRecord::Migration.add_column :table_name, :field_name, :field_type
If you're just hacking around, it's usually easier to manipulate the database using a SQLite client of some sorts than through the Rails DB layer.
If you're doing this for a project, create a proper migration file and run it.
If you're determined to do this, the add_column method is available through the ActiveRecord::Base.connection driver object.

Rails DB Migration - How To Drop a Table?

I added a table that I thought I was going to need, but now no longer plan on using it. How should I remove that table?
I've already run migrations, so the table is in my database. I figure rails generate migration should be able to handle this, but I haven't figured out how yet.
I've tried:
rails generate migration drop_tablename
but that just generated an empty migration.
What is the "official" way to drop a table in Rails?
You won't always be able to simply generate the migration to already have the code you want. You can create an empty migration and then populate it with the code you need.
You can find information about how to accomplish different tasks in a migration here:
http://api.rubyonrails.org/classes/ActiveRecord/Migration.html
More specifically, you can see how to drop a table using the following approach:
drop_table :table_name
Write your migration manually. E.g. run rails g migration DropUsers.
As for the code of the migration I'm just gonna quote Maxwell Holder's post Rails Migration Checklist
BAD - running rake db:migrate and then rake db:rollback will fail
class DropUsers < ActiveRecord::Migration
def change
drop_table :users
end
end
GOOD - reveals intent that migration should not be reversible
class DropUsers < ActiveRecord::Migration
def up
drop_table :users
end
def down
fail ActiveRecord::IrreversibleMigration
end
end
BETTER - is actually reversible
class DropUsers < ActiveRecord::Migration
def change
drop_table :users do |t|
t.string :email, null: false
t.timestamps null: false
end
end
end
First generate an empty migration with any name you'd like. It's important to do it this way since it creates the appropriate date.
rails generate migration DropProductsTable
This will generate a .rb file in /db/migrate/ like 20111015185025_drop_products_table.rb
Now edit that file to look like this:
class DropProductsTable < ActiveRecord::Migration
def up
drop_table :products
end
def down
raise ActiveRecord::IrreversibleMigration
end
end
The only thing I added was drop_table :products and raise ActiveRecord::IrreversibleMigration.
Then run rake db:migrate and it'll drop the table for you.
Warning: Do this at your own risk, as #z-atef and #nzifnab correctly point out, Rails will not be aware of these changes, your migration sequence fill fail and your schema will be different from your coworkers'. This is meant as a resource for locally tinkering with development only.
While the answers provided here work properly, I wanted something a bit more 'straightforward', I found it here: link
First enter rails console:
$rails console
Then just type:
ActiveRecord::Migration.drop_table(:table_name)
And done, worked for me!
You need to to create a new migration file using following command
rails generate migration drop_table_xyz
and write drop_table code in newly generated migration file (db/migration/xxxxxxx_drop_table_xyz) like
drop_table :tablename
Or if you wanted to drop table without migration, simply open rails console by
$ rails c
and execute following command
ActiveRecord::Base.connection.execute("drop table table_name")
or you can use more simplified command
ActiveRecord::Migration.drop_table(:table_name)
rails g migration drop_users
edit the migration
class DropUsers < ActiveRecord::Migration
def change
drop_table :users do |t|
t.string :name
t.timestamps
end
end
end
rake db:migrate
The simple and official way would be this:
rails g migration drop_tablename
Now go to your db/migrate and look for your file which contains the drop_tablename as the filename and edit it to this.
def change
drop_table :table_name
end
Then you need to run
rake db:migrate
on your console.
I wasn't able to make it work with migration script so I went ahead with this solution. Enter rails console using the terminal:
rails c
Type
ActiveRecord::Migration.drop_table(:tablename)
It works well for me. This will remove the previous table. Don't forget to run
rails db:migrate
I think, to be completely "official", you would need to create a new migration, and put drop_table in self.up. The self.down method should then contain all the code to recreate the table in full. Presumably that code could just be taken from schema.rb at the time you create the migration.
It seems a little odd, to put in code to create a table you know you aren't going to need anymore, but that would keep all the migration code complete and "official", right?
I just did this for a table I needed to drop, but honestly didn't test the "down" and not sure why I would.
you can simply drop a table from rails console.
first open the console
$ rails c
then paste this command in console
ActiveRecord::Migration.drop_table(:table_name)
replace table_name with the table you want to delete.
you can also drop table directly from the terminal. just enter in the root directory of your application and run this command
$ rails runner "Util::Table.clobber 'table_name'"
You can roll back a migration the way it is in the guide:
http://guides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations
Generate a migration:
rails generate migration revert_create_tablename
Write the migration:
require_relative '20121212123456_create_tablename'
class RevertCreateTablename < ActiveRecord::Migration[5.0]
def change
revert CreateTablename
end
end
This way you can also rollback and can use to revert any migration
Alternative to raising exception or attempting to recreate a now empty table - while still enabling migration rollback, redo etc -
def change
drop_table(:users, force: true) if ActiveRecord::Base.connection.tables.include?('users')
end
You can't simply run drop_table :table_name, instead you can create an empty migration by running:
rails g migration DropInstalls
You can then add this into that empty migration:
class DropInstalls < ActiveRecord::Migration
def change
drop_table :installs
end
end
Then run rails db:migrate in the command line which should remove the Installs table
The solution was found here
Open you rails console
ActiveRecord::Base.connection.execute("drop table table_name")
ActiveRecord::Base.connection.drop_table :table_name
if anybody is looking for how to do it in SQL.
type rails dbconsole from terminal
enter password
In console do
USE db_name;
DROP TABLE table_name;
exit
Please dont forget to remove the migration file and table structure from schema
I needed to delete our migration scripts along with the tables themselves ...
class Util::Table < ActiveRecord::Migration
def self.clobber(table_name)
# drop the table
if ActiveRecord::Base.connection.table_exists? table_name
puts "\n== " + table_name.upcase.cyan + " ! "
<< Time.now.strftime("%H:%M:%S").yellow
drop_table table_name
end
# locate any existing migrations for a table and delete them
base_folder = File.join(Rails.root.to_s, 'db', 'migrate')
Dir[File.join(base_folder, '**', '*.rb')].each do |file|
if file =~ /create_#{table_name}.rb/
puts "== deleting migration: " + file.cyan + " ! "
<< Time.now.strftime("%H:%M:%S").yellow
FileUtils.rm_rf(file)
break
end
end
end
def self.clobber_all
# delete every table in the db, along with every corresponding migration
ActiveRecord::Base.connection.tables.each {|t| clobber t}
end
end
from terminal window run:
$ rails runner "Util::Table.clobber 'your_table_name'"
or
$ rails runner "Util::Table.clobber_all"
Helpful documentation
In migration you can drop table by:
drop_table(table_name, **options)
options:
:force
Set to :cascade to drop dependent objects as well. Defaults to false
:if_exists
Set to true to only drop the table if it exists. Defaults to false
Example:
Create migration for drop table, for example we are want to drop User table
rails g migration DropUsers
Running via Spring preloader in process 13189
invoke active_record
create db/migrate/20211110174028_drop_users.rb
Edit migration file, in our case it is db/migrate/20211110174028_drop_users.rb
class DropUsers < ActiveRecord::Migration[6.1]
def change
drop_table :users, if_exist: true
end
end
Run migration for dropping User table
rails db:migrate
== 20211110174028 DropUsers: migrating ===============================
-- drop_table(:users, {:if_exist=>true})
-> 0.4607s
the best way you can do is
rails g migration Drop_table_Users
then do the following
rake db:migrate
Run
rake db:migrate:down VERSION=<version>
Where <version> is the version number of your migration file you want to revert.
Example:-
rake db:migrate:down VERSION=3846656238
Drop Table/Migration
run:-
$ rails generate migration DropTablename
exp:- $ rails generate migration DropProducts
if you want to drop a specific table you can do
$ rails db:migrate:up VERSION=[Here you can insert timestamp of table]
otherwise if you want to drop all your database you can do
$rails db:drop
Run this command:-
rails g migration drop_table_name
then:
rake db:migrate
or if you are using MySql database then:
login with database
show databases;
show tables;
drop table_name;
If you want to delete the table from the schema perform below operation --
rails db:rollback

Rails 3, I added a Table, then added a Column, now I want to add an Index

In Rails 3,
I created a table with a migration, then added a column with a migration which creates a has_many, belongs_to relationship....
I then ran rake db:migrate
I'd like to now add an Index because I forgot to add it before I can migrate. can I add that to one of the existing migration files (the create table one) or do I need to create a new migration for adding an index to an existing table?
Thanks
I usually create a new migration if I forget something like that (especially if I have already migrated in production). But if you are still in development, then you can alter your last migration file and use the redo rake command:
rake db:migrate:redo
There is also:
rake db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n).
Run this command to view all the different rake tasks:
rake -T db
Here is the section in the Rails Guide that talks about it:
http://guides.rubyonrails.org/migrations.html#rolling-back
If you would like to add your index without losing the data, you must create a new migration to add an index. Assuming your model is called Widget and the foreign model is called Zidget;
rails generate migration AddIndexToWidgets
and inside your new migration file at db/migrate/xxxxxxxxxx_add_index_to_widgets
class AddIndexToWidgets < ActiveRecord::Migration
def self.up
change_table :widgets do |t|
t.index :zidget_id # add ':unique => true' option if necessary
end
end
def self.down
change_table :widgets do |t|
t.remove_index :zidget_id
end
end
end
and then rake db:migrate as usual and voilà, you have your indexed column.
Update: If adding an index is all you're doing, there is a more concise way to write the same thing. There is no difference regarding the results. It's just that the former syntax is meant to DRY your code if you have more than one change for your table.
class AddIndexToWidgets < ActiveRecord::Migration
def self.up
add_index :widgets, :zidget_id # add ':unique => true' option if necessary
end
def self.down
remove_index :widgets, :column => :zidget_id
end
end

How to drop columns using Rails migration

What's the syntax for dropping a database table column through a Rails migration?
remove_column :table_name, :column_name
For instance:
remove_column :users, :hobby
would remove the hobby Column from the users table.
For older versions of Rails
ruby script/generate migration RemoveFieldNameFromTableName field_name:datatype
For Rails 3 and up
rails generate migration RemoveFieldNameFromTableName field_name:datatype
Rails 4 has been updated, so the change method can be used in the migration to drop a column and the migration will successfully rollback. Please read the following warning for Rails 3 applications:
Rails 3 Warning
Please note that when you use this command:
rails generate migration RemoveFieldNameFromTableName field_name:datatype
The generated migration will look something like this:
def up
remove_column :table_name, :field_name
end
def down
add_column :table_name, :field_name, :datatype
end
Make sure to not use the change method when removing columns from a database table (example of what you don't want in the migration file in Rails 3 apps):
def change
remove_column :table_name, :field_name
end
The change method in Rails 3 is not smart when it comes to remove_column, so you will not be able to rollback this migration.
In a rails4 app it is possible to use the change method also for removing columns. The third param is the data_type and in the optional forth you can give options. It is a bit hidden in the section 'Available transformations' on the documentation .
class RemoveFieldFromTableName < ActiveRecord::Migration
def change
remove_column :table_name, :field_name, :data_type, {}
end
end
There are two good ways to do this:
remove_column
You can simply use remove_column, like so:
remove_column :users, :first_name
This is fine if you only need to make a single change to your schema.
change_table block
You can also do this using a change_table block, like so:
change_table :users do |t|
t.remove :first_name
end
I prefer this as I find it more legible, and you can make several changes at once.
Here's the full list of supported change_table methods:
http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table
Clear & Simple Instructions for Rails 5 & 6
WARNING: You will lose data.
Warning: the below instructions are for trivial migrations. For complex migrations with e.g. millions of rows, read/write dbs, clusters, this advice is not for you:
1. Create a migration
Run the following command in your terminal:
rails generate migration remove_fieldname_from_tablename fieldname:fieldtype (Table name in plural, as per convention. See the documentation here. )
Example: rails g migration RemoveAcceptedFromQuotes accepted:boolean
2. Check the migration
# db/migrate/20190122035000_remove_accepted_from_quotes.rb
class RemoveAcceptedFromQuotes < ActiveRecord::Migration[5.2]
# with rails 5.2 you don't need to add a separate "up" and "down" method.
def change
remove_column :quotes, :accepted, :boolean
end
end
3. Run the migration
rake db:migrate or rails db:migrate (they're both the same)
....And then you're off to the races!
Generate a migration to remove a column such that if it is migrated (rake db:migrate), it should drop the column. And it should add column back if this migration is rollbacked (rake db:rollback).
The syntax:
remove_column :table_name, :column_name, :type
Removes column, also adds column back if migration is rollbacked.
Example:
remove_column :users, :last_name, :string
Note: If you skip the data_type, the migration will remove the column successfully but if you rollback the migration it will throw an error.
in rails 5 you can use this command in the terminal:
rails generate migration remove_COLUMNNAME_from_TABLENAME COLUMNNAME:DATATYPE
for example to remove the column access_level(string) from table users:
rails generate migration remove_access_level_from_users access_level:string
and then run:
rake db:migrate
Remove Columns For RAILS 5 App
rails g migration Remove<Anything>From<TableName> [columnName:type]
Command above generate a migration file inside db/migrate directory. Snippet blow is one of remove column from table example generated by Rails generator,
class RemoveAgeFromUsers < ActiveRecord::Migration
def up
remove_column :users, :age
end
def down
add_column :users, :age, :integer
end
end
I also made a quick reference guide for Rails which can be found at here.
You can try the following:
remove_column :table_name, :column_name
(Official documentation)
rails g migration RemoveXColumnFromY column_name:data_type
X = column name
Y = table name
EDIT
Changed RemoveXColumnToY to RemoveXColumnFromY as per comments - provides more clarity for what the migration is actually doing.
To remove the column from table you have to run following migration:
rails g migration remove_column_name_from_table_name column_name:data_type
Then run command:
rake db:migrate
remove_column in change method will help you to delete the column from the table.
class RemoveColumn < ActiveRecord::Migration
def change
remove_column :table_name, :column_name, :data_type
end
end
Go on this link for complete reference : http://guides.rubyonrails.org/active_record_migrations.html
For removing column from table in just easy 3 steps as follows:
write this command
rails g migration remove_column_from_table_name
after running this command in terminal one file created by this name and time stamp (remove_column from_table_name).
Then go to this file.
inside file you have to write
remove_column :table_name, :column_name
Finally go to the console and then do
rake db:migrate
Give below command it will add in migration file on its own
rails g migration RemoveColumnFromModel
After running above command you can check migration file remove_column code must be added there on its own
Then migrate the db
rake db:migrate
Heres one more from rails console
ActiveRecord::Migration.remove_column(:table_name, :column_name)
Step 1: Create a migration
rails g migration remove_column_name_from_table
Step 2: Change code in file migration just created
rails version < 3
def change
remove_column :table_name, :column_name, :datatype
end
rails version >= 3
def change
remove_column :table_name, :column_name
end
Step 3: Migrate
rake db:migrate
Simply, You can remove column
remove_column :table_name, :column_name
For Example,
remove_column :posts, :comment
first try to create a migration file running the command:
rails g migration RemoveAgeFromUsers age:string
and then on the root directory of the project run the migration running the command:
rails db:migrate
Through
remove_column :table_name, :column_name
in a migration file
You can remove a column directly in a rails console by typing:
ActiveRecord::Base.remove_column :table_name, :column_name
Do like this;
rails g migration RemoveColumnNameFromTables column_name:type
I.e. rails g migration RemoveTitleFromPosts title:string
Anyway, Would be better to consider about downtime as well since the ActiveRecord caches database columns at runtime so if you drop a column, it might cause exceptions until your app reboots.
Ref: Strong migration
Mark the column as ignored in the model
class MyModel < ApplicationRecord
self.ignored_columns = ["my_field"]
end
Generate a migration
$ bin/rails g migration DropMyFieldFromMyModel
Edit the migration
class DropMyFieldFromMyModel < ActiveRecord::Migration[6.1]
def change
safety_assured { remove_column :my_table, :my_field }
end
end
Run the migration
$ bin/rails db:migrate
you can use rails migration command
rails generate migration RemoveColumnNameFromTableName column_name:column_type
than you can migrate the database:
rails db:migrate
Just run this in the rails console
ActiveRecord::Base.connection.remove_column("table_name", :column_name, :its_data_type)
or
TableName.find_by_sql(“ALTER TABLE table_name DROP column_name”)

Resources