0

I had exactly the same issue posed in this SO question.

My implementation of the answer looks like this:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  ##### The next two lines are the important part ######
  has_many   :notes, class_name: LessonNotes::Engine::Note, foreign_key: "teacher_id"
  has_many   :notes, class_name: LessonNotes::Engine::Note, foreign_key: "student_id"

  has_many   :students, class_name:  "User",
                        foreign_key: "teacher_id"
  belongs_to :teacher,  class_name:  "User"
end 

However, I'm getting this error: uninitialized constant LessonNotes::Engine::Note

If I delete one of the has_many associations on the Engine and leave the other, everything works fine though...

UPDATE:

Got rid of the uninitialized constant error by changing the relevant two lines like this:

has_many   :notes, class_name: "::LessonNotes::Engine::Note", foreign_key: "student_id"
has_many   :notes, class_name: "::LessonNotes::Engine::Note", foreign_key: "teacher_id"

But now it seems that the second association overrides the first. ActiveRecord only looks for the second foreign key - in this case "teacher_id" - and ignores the first. Is this expected behavior?

Community
  • 1
  • 1
niftygrifty
  • 3,452
  • 2
  • 28
  • 49
  • 1
    what happens when you change `LessonNotes::Engine::Note` to a string? – jvnill Apr 23 '14 at 09:58
  • I tried that, but actually it won't work at all. Even with just one `has_many` association I get this error: `uninitialized constant User::LessonNotes::Engine::Note` – niftygrifty Apr 23 '14 at 10:03
  • Hmmm... Actually, I sort of half figured it out... updating now... – niftygrifty Apr 23 '14 at 10:06
  • Are you looking for something like [**polymorphic associations**](http://guides.rubyonrails.org/association_basics.html#polymorphic-associations)? – Yan Foto Apr 23 '14 at 11:47
  • @YanFoto: This is a little different. With polymorphic associations you have one foreign key that can be held by a number of different models. In this case I want to have multiple foreign keys. – niftygrifty Apr 23 '14 at 13:09
  • Alright. I don't think that there is any convenient method through the API for that and I'm sure that you have seen [this post](https://github.com/rails/rails/blob/1ca204be3a3c65b761706af9afe5144a096792b1/activerecord/lib/active_record/associations.rb#L1558). – Yan Foto Apr 23 '14 at 13:22

1 Answers1

1

Yes, it is the expected behavior. You are defining the same association (by name :notes) twice and thus the second declaration overwrites the first one.

You have to rename the associations.

has_many   :student_notes, class_name: "::LessonNotes::Engine::Note", foreign_key: "student_id"
has_many   :teacher_notes, class_name: "::LessonNotes::Engine::Note", foreign_key: "teacher_id"

And if you want to access both at the same time you could define something like this

def notes
  student_notes + teacher_notes
end
Milan Köpke
  • 1,133
  • 7
  • 8
  • Awesome. This works. But for some reason it causes my Rspec feature specs to fail with `NameError: uninitialized constant LessonNotes::Engine::Note` The stack trace points to the `notes` method at `student_notes + teacher_notes`. Any clue what's going on? – niftygrifty Apr 23 '14 at 14:32
  • Do you have a note.rb in app/models/lesson_notes/engine ? – Milan Köpke Apr 23 '14 at 14:51
  • Actually I don't. LessonNotes is an engine that's mounted like a gem in the app. – niftygrifty Apr 23 '14 at 23:41
  • Maybe you can point me to the lesson you are doing? The reason you are getting this error is because rails does not find or load the Note class from the engine. So maybe you forgot some steps of the setup process for your LessonNotes engine. – Milan Köpke Apr 24 '14 at 07:45
  • Oh it's not from a tutorial. It's just an app I'm making. When I wrote "implementation of the answer" above, I meant the way I implemented the answer from the StackOverflow question I linked to. Thanks for offering though! – niftygrifty Apr 24 '14 at 13:09