I have a model User which has a "role" attribute which can be filled with either "employee" or "manager". Now I want a relationship where a manager has_many employees and an employee belongs_to a manager.
Is it possible to do this within the same model? I can think of something like this:
has_many :employees, class_name: "User", :foreign_key => "employee_id"
belongs_to :manager, class_name: "User", :foreign_key => "manager_id"
Even if this would work, I have doubts it is the most elegant solution, because you would have 2 extra foreign keys.
I solved it by creating these relations in the user model:
has_many :employees, class_name: "User", foreign_key: :manager_id
belongs_to :manager, class_name: "User", foreign_key: :manager_id
Then I can create a manager and employee:
manager = User.create!(first_name: "Mario", last_name: "Manager", role: "manager")
employee = User.create!(first_name: "Ed", last_name: "Employee", role: "employee", manager_id: 16)
And then it is possible to use things like:
manager.employees
employee.manager
Related
I want to retrieve application.applicant.profile.first_name for the applicant and I'm not able to retrieve the profile attribute:first_name using applicant above.
Profile, application are connected by foreign key: user_id to user.Can someone suggest a way?
Here are my associations:
user.rb
class User < ApplicationRecord
has_many :applications
has_one :profile, -> { where role: 'user' }, dependent: :destroy
profile.rb
class Profile < ApplicationRecord
belongs_to :user, :class_name => 'User', :foreign_key => 'user_id'
job.rb
class Job < ApplicationRecord
has_many :applications, :dependent => :destroy
has_many :applicants, :through => :applications, :class_name => 'User'
application.rb
class Application < ApplicationRecord
belongs_to :job
belongs_to :applicant, :class_name => 'User', :foreign_key => 'user_id'
This line isn't correct...
has_one :profile, -> { where role: 'user' }, class_name: 'User', dependent: :destroy
It should be...
has_one :profile, -> { where role: 'user' }, dependent: :destroy
The class_name for :profile is Profile but you don't need to specify it as it can be derived from the symbol by rails.
After numerous permutations and combinations such as polymorphic, select & join statement or even by providing a SQL query, finally realised that it was as simple as a single statement as I knew the user_id of current user:
<% post.applications.each do |papplication| %>
<%= Profile.find_by_user_id(papplication.user_id).first_name %> <% end %>
I am having difficulties building my DB relation, if anyone could give me a little help i would greatly appreciate!
I have one table named Person and another one called Company and Company has many Persons and Person belongs_to Company
Here the trick Company has_many Person threw an attribute called person and has_many Person threw another attribute called administrator
Could be see like
Coca-cola = Company.new
jonathan = Person.new / nicolas = Person.new
Coca-cola : {
person: jonathan,nicolas
administrator: nicolas
}
I did that first migration :
def change
add_reference :persons, :person, index: true
add_reference :persons, :administrator, index: true
add_foreign_key :persons, :companys, column: :person_id
add_foreign_key :persons, :companys, column: :administrator_id
end
then I added this relation to my model
class Company < ApplicationRecord
has_many :persons,
:class_name => "Person",
:foreign_key => "person_id"
has_many :administrators,
:class_name => "Person",
:foreign_key => "administrator_id"
end
and
class Person < ApplicationRecord
belongs_to :person,
:class_name => "Company",
optional: true
belongs_to :administrator,
:class_name => "Company",
optional: true
end
And unfortunately that doesnt working, any lead on what could cause the problem ?
Thanks a lots.
Jonathan.
Let me know if I understood your problem. Requirements are:
Person belongs_to Company
Company has_many Persons
Company has_many Administrators
I guess you could solve with the following code:
class ChangePersons < ActiveRecord::Migration
def change
add_column :persons, :administrator, :boolean, default: false
end
end
class Company < ApplicationRecord
has_many :persons, -> { where(administrator: false) }
has_many :administrators,
class_name: "Person",
foreign_key: "person_id",
-> { where(administrator: true) }
end
class Person < ApplicationRecord
belongs_to :company
end
I used the Railstutorials to create followers and followed_users http://ruby.railstutorial.org/chapters/following-users#top
On the page where I want to show a specific persons' followers/followed_users, I'd like to show them based on when the relationship was created.
#users = #user.followers.order("created_at DESC")
Something like this ^^ just shows when the user was created, not when the relationship was created. How can I run this query efficiently to get the proper ordering?
def following
#users = #user.followed_users
end
def followers
#users = #user.followers
end
-User Model-
has_many :relationships, foreign_key: "follower_id", :dependent => :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
- Relationship Model -
belongs_to :follower, class_name: "User", touch: true
belongs_to :followed, class_name: "User", touch: true
validates :follower_id, presence: true
validates :followed_id, presence: true
Since your user has there two relationships, you can easily access that table with the direction you want.
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :reverse_relationships, foreign_key: "followed_id"
First Answer (when they're a follower)
You have to use the relationships table because that record gets created when you get a new follower, thus you do this:
#user.relationships.order("created_at DESC").collect { |r| User.find(r.followed) }
Second Answer (when they're followed)
#user.reverse_relationships.order("created_at DESC").collect { |r| User.find(r.follower) }
In my app there are Athletes... athletes can have many sports.
Athlete:
has_many :sports, :through => :user_sports
has_one :primary_sport, conditions: ["user_sports.primary = ?", true], class_name: "Sport"
has_many :user_sports
UserSport:
class UserSport < ActiveRecord::Base
attr_accessible :athlete_id, :sport_id, :primary
belongs_to :athlete
belongs_to :sport
end
I am trying to be able to pull back the primary_sport as a Sport object instead of the user_sport object.
Since you pull your sports objects :through user_sports, you should pull your primary_sport object :through user_sports as well.
has_one :primary_sport, :through => :user_sports, conditions: ["user_sports.primary = ?", true], class_name: "Sport"
Is it possible to make a has_one relationship work like this?
I would like to be able able to load records like this:
#person = Person.find(1) => {Person id: 1, favorite_house_id: 10}
#person.favorite_house => {House id: 10....)
class Person < ActiveRecord::Base
has_many :houses, through: :person_houses
has_one :favorite_house, through: :person_houses
end
class PersonHouse < ActiveRecord::Base
belongs_to :house
belongs_to :person
end
class House < ActiveRecord::Base
has_many :people, through: :person_houses
end
Replace the has_one relation of Person by:
belongs_to :favorite_house, :class_name => "House"
Do not forget to create a column favorite_house_id in the table of Person.