I'm building my first Rails engine and getting pretty confused already defining the associations between two models. For the reason of ease, let's say the name of the engine is Blorg, having two models Article and Author.
blorgh/article.rb
module Blorgh
class Article < ApplicationRecord
belongs_to :author, class_name: 'Blorg::Author',
foreign_key: 'blorg_author_id', optional: true
blorgh/author.rb
module Blorgh
class Author < ApplicationRecord
has_many :articles, class_name: 'Blorg::Article'
schema
create_table "blorgh_authors", force: :cascade do |t|
t.string "name"
t.boolean "inactive", default: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
create_table "blorgh_articles", force: :cascade do |t|
t.string "title"
t.bigint "blorgh_author_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["blorgh_author_id"], name: "index_blorgh_article_on_author_id"
If I try to create an article or count the articles of an author via rails c, I get those errors:
article = Blorgh::Article.new(title: 'New Article')
article.save # expect true
# ==> NoMethodError: private method `attribute' called for #<Blorgh::Article:0x00007fdc3fad4d50>
author = Blorgh::Author.create # worked
author.articles.count # expect 0
# ==> ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column blorgh_articles.author_id does not exist
Does anyone know how I can achieve those in-engine associations correctly?
The second error ("column blorgh_articles.author_id does not exist") is because Rails assumes the foreign key on a has_many
relationship is classname_id, which is author_id
in your example. You correctly set the foreign key on the belongs_to
side, but you need to specify on both sides of the relationship. So:
module Blorgh
class Author < ApplicationRecord
has_many :articles, class_name: 'Blorg::Article', foreign_key: 'blorg_author_id'
...