Rails Foreigner Plugin - ruby-on-rails-3

My user table should have a role_id ( not added in my table yet )
My role table has uses the default primary id: id
I am currently trying to use the foreigner plugin where it looks like ...
class AddForeignKeyToUserFromRole < ActiveRecord::Migration
def change
add_foreign_key( :users,:roles )
end
end
But my error is saying the following:
Mysql2::Error: Key column 'role_id' doesn't exist in table: ALTER TABLE users ADD CONSTRAINT users_role_id_fk FOREIGN KEY (role_id) REFERENCES roles(id)
What is going on?? What I'm I missing?

role_id, just like it says, and like you said?
How can you set a foreign key on a table column when the table column doesn't exist?

Related

Using a 'not in' query inside of a check constraint in SQL

I have two tables, one of student and one of staff that look as such:
create table student (
id int not null primary key
)
create table staff (
id int not null primary key
)
I want the id in each to be unique. I know this isn't how it should be in production but I'm just trying to see why my check constraint doesn't work and I'm using a simpler example to explain.
I then alter the tables to include the check as follows:
alter table student add constraint not_staff check (id not in (select id from staff))
alter table staff add constraint not_student check (id not in (select id from student))
These checks seem to be invalid.
My question is whether we're allowed to have these kinds of SQL statements inside of a check constraint. If so, why is the above constraint invalid and how would I go about fixing it.
Thanks!
You can't use queries in a check constraint in Db2. Refer to the description of the CREATE TABLE statement.
CHECK (check-condition)
Defines a check constraint. The search-condition must be true or unknown for every row of the table.
search-condition
The search-condition has the following restrictions:
...
The search-condition cannot contain any of the following (SQLSTATE 42621):
Subqueries
The easiest way to achieve your goal is not to create constraints, but create a sequence and use it in before triggers on both tables.

Can we change the primary key for the all the migration which is in production?

I'm trying to change the table primary key id to uuid. But the problem is data is already on production. There is a option to re write the whole migration but then we lost the data which we already have.
Also the table has too many association with each other. So is there a way to handle this situation?
We are using phoenix and elixir with postgres for this.
Yes. One might accomplish the task with several steps, some executing raw SQL against the database.
migration 1 creates the new column in the database, unique, not null, type :uuid (normal migration) and fills it with unique values (using ecto UUID generator, for instance)
migration 2 uses Ecto.Adapters.SQL.query/4 to reassign the primary key in the table¹
migration 3 updates all other tables referring this one, by deleting the foreign key then updating values from id to uuid and then creating a new foreign key pointing to uuid²
¹ somewhat along the following lines (untested)
defmodule MyRepo.Migrations.ChangeFK do
def up do
MyRepo.query("""
CREATE UNIQUE INDEX CONCURRENTLY foo_pkey_idx ON foo(id);
ALTER TABLE foos
DROP CONSTRAINT foo_pkey,
ADD CONSTRAINT foo_pkey PRIMARY KEY USING INDEX foo_pkey_idx;
""")
end
def down do
raise "unreversible"
end
end
² somewhat like
defmodule MyRepo.Migrations.AlterFK do
def up do
MyRepo.query("""
ALTER TABLE bars DROP CONSTRAINT foo_pkey;
UPDATE bars SET foo_id = (SELECT uuid FROM foos WHERE id = foo_id);
ALTER TABLE bars
ADD CONSTRAINT foo_pkey
FOREIGN KEY (foo_id)
REFERENCES foos (uuid);
""")
end
def down do
raise "unreversible"
end
end

How to reference foreign key of another schema table while creating table?

I have two Schemas :-
GamersProfileDB - Contain UserCredential_tbl table
DeveloperDB - Contain PlayerAchievements_tbl table
Now while creating table called PlayerAchievements_tbl , i want to reference it from another schema table Usercredential_tbl . Here is the following sql query :-
create table PlayerAchievements_tbl
(
pid number(10) references gamersprofiledb.usercredential (id),
aid number(10) references achievements (id)
);
But the above query gave me 'table or view does not exist' error
This (possible duplicate) answer adding foreign_key in ALTER operation whereas i want it to add foreign_key on CREATE TABLE operation and Moreover it also didn't specify what grants or privileges may require to execute this query
So my exact question would be :-
1) could it be possible to reference another schema table into existing schema table while creating new table ?
2) or do we need some privileges to execute this query ?
Thanks in Advance.
By default an (unprivileged) user has no permissions to see objects owned by another user. You need to GRANT the privilege using:
GRANT REFERENCES ON GamersProfileDB.UserCredential TO DeveloperDB;
or, if you also need to SELECT from the table then:
GRANT SELECT ON GamersProfileDB.UserCredential TO DeveloperDB;
Once you have permissions to reference (or select) the table then you can use:
CREATE TABLE PlayerAchievements_tbl -- Why add the "_tbl" suffix?
(
pid number(10)
CONSTRAINT PlayerAchievements__PID__FK -- name the constraint
REFERENCES GamersProfileDB.UserCredential (id),
aid number(10)
CONSTRAINT PlayerAchievements__AID__FK -- name the constraint
REFERENCES Achievements (id),
CONSTRAINT PlayerAchievements__PID_AID__PK
PRIMARY KEY ( pid, aid )
);

The columns in 'table_XXX' do not match an existing primiary key or UNIQUE constraint

I have 2 simple tables designed as shown below:
Users:
Categories:
Now I would like to set the username as foreign key on categories table so this is what I have done but getting the error as shown below:
Am I doing the right way? Or can anyone suggest me the right way of doing this ?
*NOTE: I have tried to remove the primary key from the 2 tables and added them back and tried but showing me the same error.
You are not doing it the right way - hence the error. Put userid in your categories table and join to users if you need the name.
In fact, if that field represents the person who created the category, it should be named something like CreatedByUserId. It should still reference users.userid.
Impose a unique constraint on the username column in Users table. Then you can create the FK as shown. That said, having username in both tables is not a very good design. You should remove username and include userid in Categories table and make that a FK instead.
A foreign key constraint does not have to be linked only to a primary
key constraint in another table; it can also be defined to reference
the columns of a UNIQUE constraint in another table.
in Create Foreign Key Relationships
You have to set a constraint in table Users in order to username to be unique.
Try to change in the table Categories the name of the foreign key field.
It seems that it "autowire" fields using their name. What i mean is : change Categories.username to Categories.userid.
Your column username in the table users must have a unique constraint if you want to set up the foreign key relationship in your screenshot.

Adding column with primary key in existing table

I am trying to add primary key to newly added column in existing table name Product_Details.
New Column added: Product_Detail_ID (int and not null)
I am trying add primary key to Product_Detail_ID (please note: there are no other primary or foreign key assigned to this table)
I am trying with this query but getting error.
ALTER TABLE Product_Details
ADD CONSTRAINT pk_Product_Detils_Product_Detail_ID PRIMARY KEY(Product_Detail_ID)
GO
Error:
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object name 'dbo.Product\_Details' and the index name 'pk\_Product\_Detils'. The duplicate key value is (0).
Am I missing something here? I am using SQL Server 2008 R2. I would appreciate any help.
If you want SQL Server to automatically provide values for the new column, make it an identity.
ALTER TABLE Product_Details DROP COLUMN Product_Detail_ID
GO
ALTER TABLE Product_Details ADD Product_Detail_ID int identity(1,1) not null
GO
ALTER TABLE Product_Details
add CONSTRAINT pk_Product_Detils_Product_Detail_ID primary key(Product_Detail_ID)
GO
In mysql, I was able to achieve with following query
ALTER TABLE table_name ADD new_column int NOT NULL AUTO_INCREMENT primary key
Add Primary Key to First Position
ALTER TABLE table_name
ADD column_name INT PRIMARY KEY AUTO_INCREMENT FIRST;
Reference: Stack Overflow | Tech On The Net
You are getting the error because you have existing data that does not fullfill the constraint.
There are 2 ways to fix it:
clean up the existing data before adding the constraint
add the constraint with the "WITH NOCHECK" option, this will stop sql server checking existing data, only new data will be checked
ALTER TABLE Jaya
ADD CONSTRAINT no primary key(No);
here Jaya is table name,
no is column name,
ADD CONSTRAINT is we giving the primary key keyword
If you want to add a new column say deptId to the existing table say department then you can do it using the below code.
ALTER TABLE department ADD COLUMN deptID INT;
it will create your new column named deptID.
now if you want to add constraint also along with new column while creating it then you can do it using the below code. In the below code I am adding primary key as a constraint. you can add another constraint also instead of primary key like foreign key, default etc.
ALTER TABLE department ADD COLUMN deptID INT NOT NULL ADD CONSTRAINT PRIMARY KEY(deptID);
k. friend
command:
sql> alter table tablename add primary key(col_name);
ex: alter table pk_Product_Detils add primary key(Product_Detail_ID);