How can I have two columns in one table point to the same column in another with ActiveRecord?
class Ticket < ActiveRecord::Base
belongs_to :submitter, :class_name => "User"
belongs_to :assignee, :class_name => "User"
end
Should work.Edit: Without trying it out, I'm not sure whether you need the :foreign_key parameter or not. My instinct is not, but it couldn't hurt.
Edit again: Sorry, left off the User -> Ticket associations. You didn't mention using them, and I typically will only add associations in one direction if I don't plan on using them in the other direction.
Anyway, try:
class User < ActiveRecord::Base
has_many :assigned_tickets, :class_name => "Ticket", :foreign_key => "assignee_id"
has_many :submitted_tickets, :class_name => "Ticket", :foreign_key => "submitter_id"
end
Rails ActiveRecord two fields each referencing the same table
It looks you you are confusing SchemaStatement#add_reference
and TableDefinition#references
which have completely different signatures.
If you want to setup a foreign key column where the table can't be derived from the name of the column (the first argument) you just pass foreign_key: { to_table: :teams}
.
class CreatePlayers < ActiveRecord::Migration[6.0]
def change
create_table :players do |t|
t.references :high_school_team, foreign_key: { to_table: :teams}
t.references :club_team, foreign_key: { to_table: :teams}
end
end
end
t.references :high_school_team, index: true
as recommended by the other answers is NOT equivilent. That just adds a index to the column but no foreign key constraint.You can then setup the assocations on Player as:
class Player < ApplicationRecord
belongs_to :high_school_team, class_name: 'Team'
belongs_to :club_team, class_name: 'Team'
end
You can't use a single has_many :players
assocation on the other end though as the foreign key column can be either players.high_school_team_id
or players.club_team_id
.class Team
has_many :high_school_team_players,
foreign_key: :high_school_team_id,
class_name: 'Player'
has_many :club_team_players,
foreign_key: :club_team_id,
class_name: 'Player'
end
But really a better alternative in the first place would have been to setup a join table:class Player
has_many :placements
has_one :high_school_team,
through: :placements,
source: :team
class_name: 'Team'
has_one :club_team,
through: :placements,
source: :team
class_name: 'Team'
end
class Placement
belongs_to :player
belongs_to :team
end
class Team
has_many :placements
has_many :players, through: :placements
end
Defining two references to the same column in another table
A database table cannot have two columns with the same name. This is what you'll need in order to get this to work. (I'm going to use home_team
and away_team
to help distinguish them, but obviously you could use team1
and team2
.)
rails g migration AddTeamsToMatch home_team_id:integer away_team_id:integer
This will generate a migration that looks like this:class AddTeamsToMatch < ActiveRecord::Migration
def change
add_column :matches, :home_team_id, :integer
add_column :matches, :away_team_id, :integer
end
end
Then in your Team
model, you can have the following:class Team < 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"
# Get all matches
def matches
self.home_matches + self.away_matches
end
end
In your Match
model, you can have:class Match < ActiveRecord::Base
belongs_to :home_team, class_name: "Team"
belongs_to :away_team, class_name: "Team"
# List both teams as array
def teams
[self.home_team, self.away_team]
end
end
Hopefully this helps. Same Model with different columns Rails
You probably want to look at Single Table Inheritance
Try a Developer
and Driver
that both inherit from User
and share one users
database table. Each is effectively its own model, allowing you to define totally independent associations, callbacks, validations, instance methods, etc...
They share all of the same database columns, and anything defined in the User
class will be inherited (and can be overwritten).
You will need to add a type
column to users
. All of the Developer
and Driver
columns fields should be defined for the users
table as well.
class AddTypeColumnToUsers < ActiveRecord::Migration
def change
add_column :users, :type, :string
end
end
And your modelsclass User < ApplicationRecord
end
class Driver < User
end
class Developer < User
end
Driver.new.type # => "Driver"
Developer.new.type # => "Developer"
User.new.type # => nil
User.new(type: 'Driver').class # => Driver
User.new(type: 'Developer').class # => Developer
User.new.class # => User
You can run separate queries for them just as you would any other modelDeveloper.all # queries all users WHERE type="Developer"
Driver.all # queries all users WHERE type="Driver"
User.all # queries all users no matter what type
Write your associations just as you would with any other model, and ActiveRecord will take care of everything else.class Company < ApplicationRecord
has_many :users
has_many :developers
has_many :drivers
end
class User < ApplicationRecord
belongs_to :company
end
class Driver < User
belongs_to :company
end
class Developer < User
belongs_to :company
end
c = Company.first
c.developers # => All developers that belong to the Company
c.drivers # => All drivers that belong to the Company
c.users # => All users (including developers and drivers) that belong to the Company
You can also use enum
for the type
column, and override the default type
column name if you wishclass AddTypeColumnToUsers < ActiveRecord::Migration
def change
add_column :users, :role, :integer
end
end
class User < ApplicationRecord
self.inheritance_column = :role # This overrides the the "type" column name default
enum role: { Driver: 0, Developer: 1 }
end
class Driver < User
end
class Developer < User
end
The catch with using enum
is you will have to use the capitalized name, and all of your enum
helper methods and scopes will be capitalized as well.User.Driver # => Scope that returns all drivers
Driver.all # => same as User.Driver
User.first.Driver? # => Is the user a Driver?
http://api.rubyonrails.org/classes/ActiveRecord/Inheritance.htmlhttp://siawyoung.com/coding/ruby/rails/single-table-inheritance-in-rails-4.html
Creating new table - how to set up table with two columns linking to same column in another table?
In your ExchangeRate Model define association using foreign key
has_one :base_currency, foreign_key: 'base_currency', class_name: 'Currency'
has_one :currency
now your can access both your currency and base currency like this@exchange_rate.base_currency.name
@exchange_rate.currency.name
in Rails how to select additional columns from multiple tables
result = User.first.usertags.joins(:tag).select("tags.name as tag_name, tags.id, usertags.id, user.id")
result.collect{|r| r.tag_name}
How to get records from multiple condition from a same column through associated table
ca = Category.find_by_name('CA')
cb = Category.find_by_name('CB')
Book.where(:id => (ca.book_ids & cb.book_ids)) # & returns elements common to both arrays.
Otherwise you'd need to abuse the join table directly in SQL, group the results by book_id, count them, and only return rows where the count is at least equal to the number of categories... something like this (but I'm sure it's wrong so double check the syntax if you go this route. Also not sure it would be any faster than the above):SELECT book_id, count(*) as c from books_categories where category_id IN (1,2) group by book_id having count(*) >= 2;
How to add two references column to create table migration?
You can change the Migration
file as below, adding two integer columns player1 and player2
class CreateGames < ActiveRecord::Migration[5.0]
def change
create_table :games do |t|
t.references :room, foreign_key: true
t.boolean :p1turn
t.string :secret
t.string :wordsofar
t.integer :wrongtries
t.integer :player1
t.integer :player2
end
end
end
The Game class can be like this,this belongs_to two players referencing the User class.
class Game < ActiveRecord::Base
belongs_to :player1, :class_name => "User"
belongs_to :player2, :class_name => "User"
end
Now, the User class and the players relation.class User < ActiveRecord::Base
has_many :primary_players, :class_name => "Game", :foreign_key => "player1"
has_many :secondary_players, :class_name => "Game", :foreign_key => "player2"
end
Here I referenced player1
as primary_players
and player2
as secondary_players
.Now, you can call as,
User.first.primary_players
User.first.secondary_players
Related Topics
How to Test Helpers Blocks in Sinatra, Using Rspec
Why Can't The Mail Block See My Variable
Multistep Form with Activeadmin
Automatically Adding Proxy to All Http Connections in Ruby
Algorithm to Render a Horizontal Binary-Ish Tree in Text/Ascii Form
Proper Usage of Ruby Statement Modifiers
Is It a Bad Practice to Randomly-Generate Test Data
How to Pick The Method to Call When There Is Mixin Method Name Conflict
Sorting Hash of Hashes by Value (And Return The Hash, Not an Array)
Overriding Instance Variable Array's Operators in Ruby
How to Display Image Pointed by Url in Rails
Ruby: Is It Acceptable to Put More Than One Class in a File
Accessing Microsoft Exchange Server from Ruby
Puzzled Over Palindromic Product Problem
Convert Durations in Ruby - Hh:Mm:Ss.Sss to Milliseconds and Vice Versa