1
votes

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?

1
I cant reproduce the first problem, though your example has issues that I can't tell if they are part of your code/problem or an issue with your example (e.g., by default the article table would be blorgh_articles rather than blorgh_article). However, the second problem is that Rails assumes the foreign key on a has_many relationship is classname_id (so, author_id). When using a namespaced model, you just need to specify the foreign_key on the has_many side as well as the belongs_to side.rmlockerd
Thanks @rmlockerd! That actually was it already :) I just had to add the foreign key corretly and the second issue worked. For the first, I now found it is due do a more complex validation I have. As I know that now, I can go from there. for the blorgh_article issue, this was due to my example, sorry... I edit it in the question. Feel free to put your comment as an answer, so I can mark it :)Kevin Liebholz

1 Answers

2
votes

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'
...