sigillum_conf
sigillum_conf

Reputation: 433

Rails has_one association, accessing associated models

I currently am experimenting with Rails model associations to get into better grips with them. Currently I have achieved what I wanted, which is having a relationship table that connects the data of two of my models together. The problem I am facing is that I have this feeling that there might be a better way to associate the tables from the ones that I currently have. To give a better explanation with the code that I currently have:

I have an Institution model which basically lets me add institution names(I am keeping the models as simple as possible until I have the correct method for doing this:

class Institution < ApplicationRecord
  has_many :marketings
  has_many :usermocks , through: :marketings
end

Then I have the user(its a mock table, no Devise or Sorcery until this is correct)

class Usermock < ApplicationRecord
  #has_many :marketings
  #has_many :institutions, through: :marketings
  has_one :marketing
  has_one :institution, through: :marketing
end

And finally, the relationship table which for now I have called marketing(I am trying to associate a list of individuals that work in a marketing department, kinda toying with building the model for institutions where I work at)

class Marketing < ApplicationRecord
  belongs_to :usermock
  belongs_to :institution
end

The plan is, the institution will have a set of marketers, and each marketer can only belong to one institution, hence the has_one helper on the Usermock class. It works though, if I add an institution, create a user and then pass the user to the institution it will work, my problem is that accessing the institution's data through the user needs to be done through the marketing table:

institution = Institution.create(institution_name: "Test Institution")
user_mock   = Usermock.create(user_name: "Test User 1")
institution.usermocks << user_mock # builds the relationship succesfully

The code above works, and if I wanted to show the list of users that belong inside of the marketing department in the view that represents the institution I would just go by using @institution.usermocks and it will give me what I wanted no problem, I can just loop like required and output the necessary fields.

But when I do this from the user's perspective:

user_mock.institution # Returns nil Main problem here
user_mock.marketing.institution # returns the correct information

As a novice in Rails, what could I do in order to better show this relationship? The fact that user_mock.institution returns nil seems to me like bad design on my part. I already went through the Rails Association Guide and even though it was efficient enough to show me that way through the required associations I am still missing this information.

I have also looked into: Rails has_one :through association

Rails has_one association confusion

But I am still unsure of the correct way about this, is the user_m_one.institution supposed to return nil and I am forced to go by user_m_one.marketing.institution instead?

Any pointers from y'all would be greatly appreciated.

Upvotes: 4

Views: 1449

Answers (1)

Ashik Salman
Ashik Salman

Reputation: 1879

Hope you have setup the Marketing table with foreign key columns. The migration may looks like:

class CreateMarketings < ActiveRecord::Migration[5.1]
  def change
    create_table :marketings do |t|
      t.references :usermock, foreign_key: true
      t.references :institution, foreign_key: true

      t.timestamps
    end
  end
end

Now if you query user_mock.institution, it will produce the following Query

 SELECT  "institutions".* FROM "institutions" INNER JOIN "marketings" ON "institutions"."id" = "marketings"."institution_id" WHERE "marketings"."usermock_id" = $1 LIMIT $2  [["usermock_id", usermock_id], ["LIMIT", 1]

And it will return the institution object associated with the usermock model.

Upvotes: 1

Related Questions