Rails 4 Migration | Add Table with Reference
Solution 1
This part of your migration:
t.references :collaborator, index: true, foreign_key: true
will try to create a foreign key inside the database so that the collaborator_id
column of the collaborations
table will be guaranteed to be NULL
or contain the id
of a column in the collaborators
table. You can't create that FK until the collaborators
table exists.
The error you're getting is:
relation "collaborators" does not exist
and that's just telling you that you don't have a collaborators
table but you're trying to reference it.
You need a migration to create the collaborators
table before you create your collaborations
table.
Solution 2
In Rails 5, at least, you can use foreign_key: {to_table: ... }} as follows.
create_table :messages, id: :uuid do |t|
t.references :from_user, type: :uuid, index: true, null: false, foreign_key: {to_table: :users, on_delete: :cascade}
t.references :to_user, type: :uuid, references: :user, index: true, null: false, foreign_key: {to_table: :users, on_delete: :cascade}
t.text :body, null: false
t.timestamps
end
Solution 3
sorry for being late, but essentially it's all about convenience, remember that's the essence of rails. so; every reference should be targeting the table that should be in the plural (since a table holds many "objects") therefore, you must make the reference to plural so rails will generate a reference to a singular object. button line, your migration should look more like;
class CreateCollaborations < ActiveRecord::Migration
def change
create_table :collaborations do |t|
t.references :projects, index: true, foreign_key: true
t.references :collaborators, index: true, foreign_key: true
t.boolean :accepted
t.timestamps null: false
end
end
end
Now, if you follow the conventions, then you should have no problem with the rest, just keep in mind that belong_to
is to a singular object and has_many
is to a plural object.
PS: I would not use past reference for the column, like accepted
Happy Coding
Michael Fich
Updated on July 09, 2022Comments
-
Michael Fich almost 2 years
I am attempting to create a
Collaboration
table in my Rails 4 project, but I've run into an issue. I wish it to belong_to a single user, the collaborator.I ran the following command to generate the model and the migration, which I've also copied below.
rails generate model Collaboration project:references collaborator:references accepted:boolean
Migration:
class CreateCollaborations < ActiveRecord::Migration def change create_table :collaborations do |t| t.references :project, index: true, foreign_key: true t.references :collaborator, index: true, foreign_key: true t.boolean :accepted t.timestamps null: false end end end
Model:
class Collaboration < ActiveRecord::Base belongs_to :project belongs_to :collaborator, class_name: 'User' end
I updated the Collaboration model to include
, class_name: 'User'
as shown above. Similarly, I updated the existingStrategy
model to include ahas_many :collaborations
class Project < ActiveRecord::Base has_many :collaborations end
When I run
rake db:migrate
, I get the following error reported.rake aborted! StandardError: An error has occurred, this and all later migrations canceled: PG::UndefinedTable: ERROR: relation "collaborators" does not exist
I'm a bit puzzled as to wy this is happening. Any assistance would be greatly appreciated! Thank you. :)
EDIT:
Adding code for my
User
model as well.class User < ActiveRecord::Base authenticates_with_sorcery! has_many :projects has_many :collaborations end
I edited out validations for fields such as password, email, etc to try to remove clutter.
-
MarsAtomic over 8 yearsThis is what I was thinking as well. Just to clarify, he's aliasing user as collaborator, so he needs to make sure his create_users_xxxxx.rb migration takes place before this create_collaborations_yyyyy.rb migration.
-
Michael Fich over 8 yearsHmm, I have a users table which was set up earlier in my project. I tried to add a separate migration to add a collaborator reference to the collaborators table however I ran into the same error with that migration as I encountered with the first.
-
Michael Fich over 8 years@MarsAtomic - That's exactly right! The issue is because I am trying to reference the users table while aliasing it as "collaborator". Still working through the errors though.
-
mu is too short over 8 yearsSo
collaborations.collaborator_id
is supposed to be ausers.id
value? How do you feel about usingt.references :user
instead? -
Michael Fich over 8 years@muistooshort - That's something I could look to use if I can't get this sorted out. I'd like to get it figured out as it's currently constructed first, if possible.
-
mu is too short over 8 yearsAs near as I can tell, you can (1) use
user_id
as the column name (i.e.t.references :user
), (2) don't use an FK (i.e.foreign_key: false
), or (3) add the database FK by hand with a bit of SQL. (1) is the most Railsy I suppose, (2) is a shortcut to broken data in your database, (3) will require switching yourschema.rb
tostructure.sql
. The docs don't seem to offer anything else. I do (3) because I use all kinds of things in the database that AR doesn't understand.