Mohammad Areeb Siddiqui
Mohammad Areeb Siddiqui

Reputation: 10179

Reference a single column from one table 2 times to another table

I have two tables:

  1. users
  2. posts

A post belongs to a user and a post can be awarded to another user. How can I map this association in rails models?

These are my current associations, which are not working:

class Post < ActiveRecord::Base

    belongs_to :user
    has_one :awarded_user, :class_name => 'User', :foreign_key => 'awarded_to_user_id'

When I try to access post.awarded_user, I get this error in rails console:

ActiveRecord::StatementInvalid: Mysql2::Error: Unknown column 'users.awarded_to_user_id' in 'where clause': SELECT  `users`.* FROM `users` WHERE `users`.`awarded_to_user_id` = 8 LIMIT 1

The query searches for user.awarded_to_user_id however, I need it to search in posts to become posts.awarded_to_user_id.

How can I solve this issue?

Upvotes: 1

Views: 364

Answers (1)

Arslan Ali
Arslan Ali

Reputation: 17802

First of all, generate a migration that adds a column into posts table.

class AddAwardedToUserIdToPosts < ActiveRecord::Migration                   
  def change                                                                
    add_column :posts, :awarded_to_user_id, :integer, index: true
  end                                                                      
end

And now, in your model:

class User < ActiveRecord::Base                                             
  has_many :posts                                
  has_one :awarded_post, class_name: 'Post', foreign_key: 'awarded_to_user_id'  
end

And for Post

class Post < ActiveRecord::Base                                             
  belongs_to :awarded_user, class_name: 'User', foreign_key: 'awarded_to_user_id'
  belongs_to :user
end

And now, in this case, you can achieve what you are saying:

user_zaid = User.create first_name: "Zaid"
user_ali = User.create first_name: "Ali"

post = Post.create description: "A less descriptive post"

post.user = user_zaid
post.awarded_user = user_ali

post.save


# Or the other way

user_ali.posts << post # Since, user has_many posts.
user_ali.awarded_post = post # Since, user has_one awarded_post. 

user_ali.save

# How to fetch:

User.last.posts # it will give you the posts.
User.last.awarded_post # it will give you the (single) awarded post. 

And for Post,

Post.last.user # it will give you the user which it belongs to
Post.last.awarded_user # it will give you the user which it was **awarded** to

Upvotes: 1

Related Questions