Everytimes, I have a column for my event object (event-calendar gem) in my schema.rb file
t.integer "id", :null => false
So of course, every time I want to create an event I have an error "null value in column "id" violates not-null constraint" because of this. I tried this solution ActiveRecord::StatementInvalid: PG::Error: ERROR: null value in column "id" violates not-null constraint but it appears everytimes !!! I would like to know WHY this column appears here, I really don't understand...
Any idea ?
When you created the events model, it sounds like you added an id field. This isn't necessary as rails automatically creates this field. Your event model in your schema should look something like:
create_table "events", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
I would rollback the migration, assuming this is the most recent migration:
rake db:rollback
Then update the migration file and remove the id from the create_table block:
class CreateEvents < ActiveRecord::Migration
def change
create_table :events do |t|
t.string :name
t.timestamps
end
end
end
Then rerun the migration.
Related
I am trying to add a new column active to my table students.
I ran rails g migration add_active_to_students active:boolean to generate this migration:
class AddActiveToStudents < ActiveRecord::Migration[5.0]
def change
add_column :students, :active, :boolean, default: true
end
end
But when I run rails db:migrate I get this error:
PG::DuplicateColumn: ERROR: column "active" of relation "students" already exists
: ALTER TABLE "students" ADD "active" boolean DEFAULT 't'`
As you can see there is not actually an active column in students:
create_table "students", force: :cascade do |t|
t.integer "club_id"
t.string "email"
t.string "address_line_1"
t.string "address_line_2"
t.string "city"
t.string "state"
t.integer "postcode"
t.string "phone1"
t.string "phone2"
t.string "first_name"
t.string "last_name"
t.date "dob"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "picture"
t.integer "payment_plan_id"
t.string "parent1"
t.string "parent2"
t.string "size"
t.text "notes"
t.index ["club_id"], name: "index_students_on_club_id", using: :btree
end
So why would I be getting this error?
I followed the steps that #demir posted and found that, yes, the column was in the database without being listed in the schema. ALTER TABLE students DROP COLUMN active did not give an error message however it also didn't remove the column.
In the end I removed it by:
Entering the console
rails console
Deleting the column
ActiveRecord::Base.connection.remove_column :students, :active
You may have added it somehow. Have you checked the PG database? Connect to the application database and see if there is an active field.
List databases
\l
Connect database
\c your_app_database_name
List table columns
\d+ students
Check active field, remove it if exist.
ALTER TABLE students DROP COLUMN active
You have this column in your DB, but it wasn't dumped to your schema.rb. Maybe a migration was stopped after it added the column, but before it wrote to schema.rb?
You can remove this column manually, running rails dbconsole and then:
ALTER TABLE students DROP COLUMN active
You can follow the above solutions i.e. drop the column from DB first and then run the migration. Most probably what has happened is, you created and run some migration but later deleted that migration file without doing a db:rollback.
One more option that you can consider is to put a conditional migration like:
class AddActiveToStudents < ActiveRecord::Migration[5.0]
def change
unless column_exists? :students, :active
add_column :students, :active, :boolean, default: true
end
end
end
If I add a default value to an existing column through an ActiveRecord Migration, when deploying my changes to production, existing associations are not affected.
I can drop to a rails production console and iterate over every single record and set the value on the new column to false on each record however it's tedious and doesn't scale well.
class AddDefaultValuesToAFewColumns < ActiveRecord::Migration[5.2]
def change
change_column :downloads, :is_deleted, :boolean, :default => false
end
end
create_table "downloads", force: :cascade do |t|
t.string "version"
t.string "comment"
t.string "contributors"
t.string "release_date"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "download_url"
t.boolean "is_deleted", default: false
end
The expected result would be for associations when queried from the rails console to return false for is_deleted, rather it returns nil. Why is this and what alternative solutions are there?
That's how it works. When you change the column default value, you are configuring the default value for new records, not existing ones. If you want to update existing values with false then do something like Download.where(is_deleted: nil).update_all(is_deleted: false) right after the change_column line:
class AddDefaultValuesToAFewColumns < ActiveRecord::Migration[5.2]
def change
change_column :downloads, :is_deleted, :boolean, :default => false
Download.where(is_deleted: nil).update_all(is_deleted: false)
end
end
I use Rails 4, SQLite version 3.8.2 and I would like to add new column to my db.
I create new migration:
rails g migration AddFooToStudents foo:string
so I get then :
class AddFooToStudents < ActiveRecord::Migration
def change
add_column :students, :foo, :string, after: :name
end
end
then I run migration:
rake db:migrate
== 20150803095305 AddFooToStudents: migrating
=================================
-- add_column(:students, :foo, :string, {:after=>:name})
-> 0.0009s
== 20150803095305 AddFooToStudents: migrated (0.0011s)
========================
Everythink seems to be OK, in database has been added foo column but instead of after name column, it has been added at the end of table
ActiveRecord::Schema.define(version: 20150803095305) do
create_table "students", force: :cascade do |t|
t.string "name"
t.string "lastname"
t.integer "age"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "second_name", default: "Untitled"
t.string "foo"
end
end
I completely don't know what I do wrong
You're using the after option, and so you could reasonably expect it to put it after :name.
However, this isn't documented very well (if at all) but the after option only works in some DBMSs (possibly only MySQL).
What i do is add my own sql to do this, after the add_column call, like so:
add_column :students, :foo, :string
ActiveRecord::Base.connection.execute("ALTER table students MODIFY COLUMN foo varchar(255) AFTER name")
Your SQL will need to be DBMS-specific, ie tailored to MySql, PostGresql, SQLite etc.
Well, SQLite does not handle AFTER syntax so in this situation the best solution is leave unchanged order of columns or create new table.
I have a error without explanation.
My error :
G::UndefinedColumn: ERROR: column "conjoncture_index_id" referenced in foreign key constraint does not exist
: ALTER TABLE "reports" ADD CONSTRAINT "fk_rails_c25ad9a112"
FOREIGN KEY ("conjoncture_index_id")
REFERENCES "conjoncture_indices" ("id")
My migration :
class AddColumnToReports < ActiveRecord::Migration
def change
add_reference :reports, :conjoncture_indice, index: true
add_foreign_key :reports, :conjoncture_indices
end
end
My create table migration :
class CreateConjonctureIndices < ActiveRecord::Migration
def change
create_table :conjoncture_indices do |t|
t.date :date
t.float :value
t.timestamps null: false
end
end
end
My model :
class ConjonctureIndice < ActiveRecord::Base
has_many :reports
by_star_field :date
end
My ConjonctureIndice shema.rb part :
create_table "conjoncture_indices", force: :cascade do |t|
t.date "date"
t.float "value"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
I'm looking for "conjoncture_index" in my project but nothing... I think that a old version of the project uses "conjoncture_index" instead "conjoncture_indice" but all occurence are deleted.
In rails , The migration names are plural whereas the model names are singular . So the model name should had been Index but it cannot be as it's a reserved keyword , the plural of which transforms to ConjunctureIndices .
Note - If you are still in doubt , then you can drop and re-create the database but i suspect the naming convention to be an issue in your case .
Ok i found the problem. i think that the error message is the same as before but he refer to a other table called "confidence_indices". The error come from "indice" word.. when i delete it i have no problem.
I wrote a migration for a join model which looks like:
create_table "project_memberships", :id => false, :force => true do |t|
t.integer "user_id"
t.integer "project_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "id"
end
I want to forcibly create ids now. Must I drop the table and recreate it or can I write a migration removing this constraint?
With a small amount of googling... http://thinkwhere.wordpress.com/2009/05/09/adding-a-primary-key-id-to-table-in-rails/
Generate a empty migration:
rails generate migration AddIdToProjectMemberships
and fill it in with:
def change
add_column :project_memberships, :id, :primary_key
end
Also there was a question like this before.. how to add a primary key to a table in rails