Rails has_many through multiple foreign keys
the default join in has_many :children
in house.rb is between the children and parents table depending on the parent_id
column that is not exist.
so you need to override it: so house.rb should look like below.
class House < ApplicationRecord
has_many :parents
has_many :children, -> { unscope(:joins).joins('INNER JOIN ON children.father_id = parents.id OR children.mother_id = parents.id') }, through: :parents
end
has_many through with multiple foreign keys on table
This is what jvillian commented, which is in fact an answer
class FeedPost < ApplicationRecord
has_many :flights
has_many :destinations, through: :flights, source: :destination
has_many :origins, through: :flights, source: :origin
def locations
(origins + destinations).uniq
end
Rails association with multiple foreign keys
TL;DR
class User < ActiveRecord::Base
def tasks
Task.where("owner_id = ? OR assigneed_id = ?", self.id, self.id)
end
end
Remove has_many :tasks
in User
class.
Using has_many :tasks
doesn't make sense at all as we do not have any column named user_id
in table tasks
.
What I did to solve the issue in my case is:
class User < ActiveRecord::Base
has_many :owned_tasks, class_name: "Task", foreign_key: "owner_id"
has_many :assigned_tasks, class_name: "Task", foreign_key: "assignee_id"
end
class Task < ActiveRecord::Base
belongs_to :owner, class_name: "User"
belongs_to :assignee, class_name: "User"
# Mentioning `foreign_keys` is not necessary in this class, since
# we've already mentioned `belongs_to :owner`, and Rails will anticipate
# foreign_keys automatically. Thanks to @jeffdill2 for mentioning this thing
# in the comment.
end
This way, you can call User.first.assigned_tasks
as well as User.first.owned_tasks
.
Now, you can define a method called tasks
that returns the combination of assigned_tasks
and owned_tasks
.
That could be a good solution as far the readability goes, but from performance point of view, it wouldn't be that much good as now, in order to get the tasks
, two queries will be issued instead of once, and then, the result of those two queries need to be joined as well.
So in order to get the tasks that belong to a user, we would define a custom tasks
method in User
class in the following way:
def tasks
Task.where("owner_id = ? OR assigneed_id = ?", self.id, self.id)
end
This way, it will fetch all the results in one single query, and we wouldn't have to merge or combine any results.
has_many association with multiple foreign keys to the same table
You'll need something like:
class Team < ActiveRecord::Base
has_many :home_games, class_name: 'Game', foreign_key: 'home_team_id'
has_many :away_games, class_name: 'Game', foreign_key: 'away_team_id'
# This seems like a separate thing to me...
has_many :winning_games, class_name: 'Game', foreign_key: 'winning_team_id'
# Do not include winning games, since it would already be included
def games
self.home_games.to_a + self.away_games.to_a
end
end
Multiple Foreign Keys _ has_many
You can accomplish this without relying on the dependent
command of an association. The best way I can think of is to 'clean out' the associations when the action is taken to disassociate the Profile
from an Organization
. You could have an inverse method in Organization
.
class Profile < ActiveRecord:Base
def method_that_disassociates_from(inputted_organization)
self.organizations.delete(inputted_organization)
self.notifications.where(organization_id: inputted_organization.id).destroy_all
end
end
Rails Model has_many with multiple foreign_keys
Found a simple answer on IRC that seems to work (thanks to Radar):
class Person < ActiveRecord::Base
belongs_to :father, :class_name => 'Person'
belongs_to :mother, :class_name => 'Person'
has_many :children_of_father, :class_name => 'Person', :foreign_key => 'father_id'
has_many :children_of_mother, :class_name => 'Person', :foreign_key => 'mother_id'
def children
children_of_mother + children_of_father
end
end
Rails multiple foreign keys in the same table
Does table procedures need to have both the fields owner_id and
assignee_id, or just a field user_id
You should have both owner_id
and assignee_id
in procedures
table instead of user_id
so that you can call
@user.owned_procedures
@user.assigned_procedures
to get owned_procedures
and assigned_procedures
of a @user
which is an instance of User
. And to get a owner
and assignee
of a procedure, call
@procedure.owner
@procedure.assignee
Has_many, belongs_to with multiple foreign keys
You could define foreign keys
class Club < ActiveRecord::Base
has_many :home_matches, class_name: 'Match', foreign_key: 'home_team_id'
has_many :away_matches, class_name: 'Match', foreign_key: 'away_team_id'
end
But I suspect this will cause more problems as you'd presumably want to get all matches and order by date, which you could do by doing two queries and adding the results and sorting but that is frankly messy.
My initial thought it that you ought to be looking at a has many through relationship it you want to be able to do @club.matches
class Club < ActiveRecord::Base
has_many :club_matches
has_many :matches, through: :club_matches
end
class ClubMatch < ActiveRecord::Base
belongs_to :club
belongs_to :match
#will have an attribute on it to determine if home or away team
end
class Match < ActiveRecord::Base
has_many :club_matches
has_many :clubs, through: :club_matches
end
Then you'd be able to do @club.matches
Just my initial thought and someone may well come up with a better solution
Presumably though you could just do a query without the association which might be better and less refactoring for you. For example
class WhateverController < ApplicationController
def matches
@club = Club.find(params[:club_id)
@matches = Match.where("home_team_id = :club_id OR away_team_id = :club_id", {club_id: @club.id}).order(:date)
end
Related Topics
Group Hashes by Keys and Sum the Values
When to Use 'Self.Foo' Instead of 'Foo' in Ruby Methods
How to Create an Average from a Ruby Array
Creating Matrix With 'Array.New(N, Array.New)'
How to Use Ruby/Rails Variables Inside Sass
How to Download a File from a Url and Save It in Rails
Can't Install Rmagick 2.13.1. Can't Find Magickwand.H.
Rails: What's a Good Way to Validate Links (Urls)
Ruby'S File.Open and the Need For F.Close
Submit Post Data from Controller to Another Website in Rails
Calling a Method from a String With the Method'S Name in Ruby
Validation for Non-Negative Integers and Decimal Values
Operator Precedence For And/&& in Ruby
How to Avoid "Cannot Load Such File - Utils/Popen" from Homebrew on Osx