I am trying to do a self-join. I generated this migration to make a correct primary. This code works, but I'm not sure if this is the best way to do things.
class CreateFeedstocks < ActiveRecord::Migration[5.0]
def change
create_table :feedstocks do |t|
t.string :code
t.float :measure_one
t.float :measure_two
t.float :measure_three
t.string :description
t.integer :primary_feedstock_id, index: true
t.timestamps
end
add_foreign_key :feedstocks, :feedstocks,
column: :primary_feedstock_id,
primary_key: :id
end
end
One feedstock has one primary_feedstock
and one primary_feedstock
has
many feedstocks
.
1 Answer 1
Does the format provided in the Rails Guides not work for you?
# Model ------------------------------------------------------------------------
class Feedstock < ApplicationRecord
has_many :feedstocks, foreign_key: "primary_feedstock_id"
belongs_to :primary_feedstock, class_name: "Feedstock"
end
# Migration --------------------------------------------------------------------
class CreateFeedstocks < ActiveRecord::Migration[5.0]
def change
create_table :feedstocks do |t|
t.references :primary_feedstock, index: true
t.timestamps
end
end
end
EDIT: So I'm still not clear on the difference between add_foreign_key
and t.references
. According to this comment on SO, t.references
will not create a foreign key constraint, but that was written 5 years ago, and the part of the Guides that the commenter mentioned is no longer there.
The API docs are abundantly clear about add_foreign_key
creating a foreign key constraint at the database level; unfortunately, they're not so clear about t.references
.
In any case, you will have to decide for yourself how to design your application. I've heard some people say that depending on ActiveModel is ‘the Rails Way’, but I haven't seen that position stated anywhere in the official docs. Alternately, others will tell you that implementing these checks at the database level is more performant and reliable, and I can't argue with that. I think in the end, the choice comes down to how strictly you believe in Rails' convention-over-configuration philosophy, and whether you're willing to sacrifice a little abstraction for performance and reliability.
EDIT 2: It appears that add_foreign_key
alone is not sufficient to create a table column. You'll need t.references
either way, followed by either the foreign_key: true
option or a separate add_foreign_key
directive.
measure_one
,measure_two
,measure_three
as an array field in db. what if you will need 4-5-6? \$\endgroup\$