1

I have two models

class User 
   has_many :disputes
end

class Dispute
   belongs_to :user
end

So Dispute has :user_id, but my problem is that a Dispute has 2 sides - the claimant and the indicted, both of which are users.

I tried to solve this problem by creating two columns: :claimant_id and :indicted_id, and passing arguments like @dispute.claimant_id = current_user.id, but after that I can't use a relationship tricks like @dispute.user.name or @user.disputes with my :claimant_id and :indicted_id.

Is there any way to set up two :user_id (like a claimant and an indicted) in one model and still maintain the relationships between Dispute and User models?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
anndrew78
  • 196
  • 1
  • 20

2 Answers2

1

You can go the route of having :claimant_id and :indicted_id on your users table, but in your class def you need

class Dispute < ActiveRecord::Base
  belongs_to :claimant, class_name: 'User', :foreign_key => :claimant_id
  belongs_to :indicted, class_name: 'User', :foreign_key => :indicted_id
end

Reference: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to

devkaoru
  • 1,142
  • 9
  • 7
0

I think this is a duplicate of Ruby on Rails Double Association

For your case use class_name as the second parameter to your belongs_to function and a hash with foreign_key and the id column name (as pointed out by @devkaoru), like so:

class Dispute < ActiveRecord::Base
  belongs_to :claimant, class_name: 'User', :foreign_key => :claimant_id
  belongs_to :indicted, class_name: 'User', :foreign_key => :indicted_id
end

I think that should do it up right.

Disclaimer: This is an untested solution

Community
  • 1
  • 1
OneHoopyFrood
  • 3,829
  • 3
  • 24
  • 39
  • If it's a duplicate, it's sufficient to flag it as such. The OP will e able to access the earlier question via boilerplate text that Stack Overflow adds after you flag a dupe. – MarsAtomic May 27 '15 at 01:07
  • Yes, it's sufficient. But I belive it's good to also answer the question more specifically in some cases (such as this, where there isn't a ton of helpful information and the OP is obviously new) as it helps out the OP a bit more. – OneHoopyFrood May 27 '15 at 01:20
  • Good solution. Thank to devkaoru and OneHoopyFrood) Have the last question. How to use relationships? Is it working for example @claimant.disputes or @dispute.indicted.name? – anndrew78 May 27 '15 at 09:23
  • Try it and find out! Then let me know. – OneHoopyFrood May 27 '15 at 12:00
  • In rails console dispute.indicted.name work pretty fine, but reverse relationship indicted.disputes not work. I think I can use indicted_disputes = Dispute.select {|x| x.indicted_id == current_user.id}, but I don't have any idea how fast this works with huge database. Is the other way to use indicted-relationship and load some data like indicted.dispute.reason? – anndrew78 May 27 '15 at 13:36
  • Yep, it has. I try to create some method in disputes_controller : sent_disputes (where user.id == claimant_id) and received_disputes (where user.id == indicted_id). I try to change the question: how to setup user like claimant? Usual way to setup user = User. find(params[:user_id]), I want build something similar: claimant = User.find(params[:claimant_id]) and after do claimant.disputes (where shall be only disputes where user is a claimant) – anndrew78 May 27 '15 at 14:25
  • Unfortunately that is a non-trivial problem. It means you need to create the methods you were talking about earlier I think. There may be a way to do it more naturally but I'm not rails savvy enough to know how. You should ask another question that's more specific to that need. – OneHoopyFrood May 27 '15 at 14:36
  • Glad to be of help. Don't forget to upvote answers that helped you! – OneHoopyFrood May 27 '15 at 15:57