Rails association with multiple custom field names? - ruby-on-rails

I have Members and Skills tables.
Each member record has 3 links to a skill: skill_primary, skill_secondary and skill_tertiary.
Each of those columns is just an ID that corresponds to a row in the Skills table.
What I want to be able to do is is reference a members given skill and get that record from the sills table.
So: member.skill_primary would return the actual Skill record.
What type of associations would I set up to pull that off?

To do this you need to declare 3 belongs_to associations and use the :class_name and :foreign_key options.
class Member < ActiveRecord::Base
belongs_to :skill_primary, class_name: 'Skill', foreign_key: :skill_primary
belongs_to :skill_secondary, class_name: 'Skill', foreign_key: :skill_secondary
belongs_to :skill_tertiary, class_name: 'Skill', foreign_key: :skill_tertiary
end
For documentation on these options, see section 4.1.2 of the Rails Guide for Active Record Associations: http://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference

Related

Rails: Single-table inheritance with many-to-many self-join relationships between records

I am modeling a learning web app with two distinct roles, Teachers and Students. There is a lot of common behaviour between both and it makes sense to abstract them to an AppUser base class. It also helps to use single-table inheritance for the two models, with a single table app_users storing both types.
Now a Teacher can have many Students, and a Student could be enrolled in courses by many different Teachers. So it's a proper many-to-many relationship. How may I model a many-to-many relationship between records in a single table.
I think one option is to use a join table on AppUser - something like app_users_app_users, with a teacher_id and a student_id column. What's the syntax to define this?
An alternative is to use a model, like AppUserRelationship, and then define has_many through relations. What's the way to do this?
this just an idea, create new relation table to hold many to many relation between
class Relation < ActiveRecord::Base
belongs_to :student, foreign_key: "student_id", class_name: "User"
belongs_to :teacher, foreign_key: "teacher_id", class_name: "User"
end
class User < ActiveRecord::Base
# as teacher
has_many :student_relations, foreign_key: :teacher_id, class_name: "Relation"
has_many :students, through: :student_relations, source: :student
# as student
has_many :teacher_relations, foreign_key: :student_id, class_name: "Relation"
has_many :teachers, through: :teacher_relations, source: :teacher
end

Creating has_one association within the same model

Let us consider the below model.
User{ id:number(primary_key), column1:string, column2:string)
Now, the column1 can be any string, but column2 can be either null, or have values from column1. However column1 and column2 can't be same. I.E. column2 will be the foreign key and it will reference column1.
How will i create a has_one relationship with these constraints.
Something like,
has_one :master_agreement, :class_name => 'User', :foreign_key => 'column2', :primary_key => 'column1'
but the above mentioned doesn't work for me.
To setup a self-joining relationship in rails you want to use belongs_to not has_one as the key difference is that belongs_to places the foreign key column on the model's table - while has_one places it on the other end.
class User < ActiveRecord::Base
belongs_to :company # references users.company_id
has_one :company # references companies.user_id
end
Lets consider a system where you have a hierarchy of categories:
class Category < ActiveRecord::Base
belongs_to :parent, class_name: 'Category'
has_many :subcategories, class_name: 'Category', foreign_key: 'parent_id'
end
This creates a self joining relationship with the categories.parent_id foreign key column which references categories.id.
While you could potentially use something different than categories.id as the reference you are just making things harder on yourself as the id column already is an indexed primary key column.

Understanding use of foreign_key and class_name in association

I am new to rails and this is a very basic question. I am trying to understand the need of foreign key and class_name.
has_many :task, foreign_key: "created_by"
has_many :memberships, class_name: "TaskMembership"
Can anyone explain the need of foreign_key & class_name.
Here is the answer of my question
Suppose you have a User model and Post model.And you have to set an association like User has many post
User Model
has_many :posts
Post Model
belongs_to :user
Now suppose your user is some author so we have to set some meaningful name so instead of user we will use author but have to specify which class it is referring
Post Model
belongs_to :author, class_name: 'User'
Now problem will occur because rails will look for author_id column in posts table .So here foreign key will come into picture.We will have to find user_id
Post Model
belongs_to :author, class_name: 'User', foreign_key: 'user_id'
See more better explanation association
has_many association is used for for one-to-many type relationships in rails. For instance, if you have a model User which can has many profiles, your User to Profile association will be has many.
class User < ActiveRecord::Base
has_many :profiles
end
class Profile < ActiveRecord::Base
belongs_to :user
end
If you have a foreign key different than user_id in profiles table, you explicitly specify foreign_key. Same is the case with class name. If your association name is different than actual model name, you explicitly specify class name after association (as you did for memberships).
Hope it helps.
in your model
class First < ActiveRecord::Base
has_many :seconds
end
class Second < ActiveRecord::Base
belongs_to :first
end
and in your second class table,create first_id column

how to add one more connection to a model?

For example, I have 2 models:
ticket.rb
belongs_to :user
user.rb
has_many :tickets, dependent: :destroy
In the table Tickets I have
t.integer "user_id"
This all works fine. But what if I wish to add a new field assignee_id, and that should be a user from the same table Users?
I can add just a field assigne_id and populate it with user_id I need, but I would like to use a construction like #ticket.assignee.name like I use for #ticket.user.name. Please could you help me?
You can do, Rails allows you to pass bunch of parameters to belongs_to. In your case, You need to specify the foreign key and the class name of the association.
This is how you can join assignee to user table
#ticket.rb
belongs_to :assignee, foreign_key: "assignee_id", class_name: "User"
source: edgeguides.rubyonrails.org
source: api.rubyonrails.org

Rails self referential data

I currently have a model named Skill. I want skills to have the possibilities have having parents and children skills.
What I currently have:
class Skill < ActiveRecord::Base
has_many :children, foreign_key: :parent_id, class_name: Skill
has_many :parents, foreign_key: :child_id, class_name: Skill
end
However, this is not picking up on the join table that I have created for this (skill_relations).
How would I either specify the table that I have created, or what should the proper name of the join table so that rails can pick this relationship up automatically?
When you use has_many, Rails assumes that the associated table is derivable from the symbol you've provided (e.g. the table children for :children).
If you want to have a separate "relations" table, you specify it with the through parameter, as in:
has_many :children, foreign_key: :parent_id, through: :skill_relations
has_many :parents, foreign_key: :child_id, through: :skill_relations

Resources