class Card < ApplicationRecord
has_one :card_rating
has_one :rating, through: :card_rating
end
class Rating < ApplicationRecord
has_many :card_ratings
has_many :cards, through: :card_ratings
end
class CardRating < ApplicationRecord
belongs_to :card
belongs_to :rating
end
I want to do something along the lines of the following:
c = card.card_rating.new
c << rating
But there doesn't seem to be any association going on at all, because already at the first statement I receive the following error:
undefined method `new' for nil:NilClass
You do not need a join table for a one to many relation:
class Card
belongs_to :rating
end
class Rating
has_many :cards
end
Rather you would use has_one :through in case the domain dictates that the relation is indirect.
class Student
belongs_to :school
has_one :headmaster, through: :school
end
class School
has_many :students
end
class Headmaster
belongs_to :school
has_many :students, through: :school
end
Related
Given these 4 Rails models:
class Apple < ActiveRecord::Base
has_one: ?
end
class Banana < ActiveRecord::Base
has_one: ?
end
class FruitMapping < ActiveRecord::Base
belongs_to :fruit, polymorphic: true
has_one :cart
end
class Cart < ActiveRecord::Base
end
How can I connect the has_one of the Apple/Banana to Cart, so that when I write apple.cart I will get the relevant Cart (through the mappings table)?
class Apple < ActiveRecord::Base
has_one :fruit_mapping, as: :fruit
end
class Cart < ActiveRecord::Base
has_many :fruit_mappigns
has_many :apples, through: :fruit_mappings, source: :fruit, source_type: 'Apple'
has_many :bananas, through: :fruit_mappings, source: :fruit, source_type: 'Banana'
end
Using the source and source_type options, you can define the polymorphic relationships. If using source and source_type are depricated in the Rails version you're using you can try
has_many :apples, through: :fruit_mappings, class_name: 'Apple', foreign_key: :fruit_id
A Group can have many keywords and a Keyword can have many groups. I have this relationship defined as
class Keyword < ActiveRecord::Base
has_many :groups_keywords
has_many :groups, through: :groups_keywords
end
class GroupsKeyword < ActiveRecord::Base
belongs_to :groups
belongs_to :keywords
end
class Group < ActiveRecord::Base
has_many :groups_keywords
has_many :keywords, through: :groups_keywords
end
I can do Group.find(1).groups_keywords so the relationship is working?
But I want to get all of my Groups keywords so I do the following.
Group.find(1).keywords
But I get the error uninitialized constant Group::Keywords
Try changing the below
class GroupsKeyword < ActiveRecord::Base
belongs_to :groups
belongs_to :keywords
end
to
class GroupsKeyword < ActiveRecord::Base
belongs_to :group
belongs_to :keyword
end
I have to create relationship between student, courses and enrolment.
One student can enrol in only one course.
A course can be enrolled by many students.
How to acheive this ?
I was able to create has_many_through relationship like this
class
Student < User
has_many :enrollments
has_many :course , through: :enrollments
end
class Course < ActiveRecord::Base
has_many :enrollments
has_many :students, through: :enrollments, class_name: "User"
end
class Enrollment < ActiveRecord::Base
belongs_to :student, class_name: "User"
belongs_to :course
end
But this works only for has_many on both the sides of students and courses.
But I want only one student to enrol in one course like this
class Student < User
has_one :enrollment
has_one :course , through: :enrollment
end
But this does not work. When I do this
Student.first.enrollment.create(course: Course.last)
I get an error like this
NoMethodError: undefined method `enrollment' for #<Student:0x007f7ff8baf4a8>
Thanks to Marek Lipka for suggesting this solution.
Add validation in Enrollment
class Enrollment < ActiveRecord::Base
belongs_to :student, class_name: "User"
belongs_to :course
validates :student , uniqueness: true
end
And use has_many enrollments
class Student < User
has_many :enrollments
has_many :course , through: :enrollments
end
Suppose I have 3 Models like this (not sure if this is correct):
class User < ActiveRecord::Base
has_many :lessons
has_many :points, through: :progress
end
class Progress < ActiveRecord::Base
belongs_to :user
has_many :lessons
end
class Lesson < ActiveRecord::Base
belongs_to :progress
end
(The Progress table has user_id and lesson_id fields.)
How would I make it so calling #user.points would return the amount of entries into the Progress table. Also, how would I build a relationship?
class User < ActiveRecord::Base
has_many :progresses
has_many :lessons, through: :progresses
end
class Progress < ActiveRecord::Base
belongs_to :user
belongs_to :lesson
end
class Lesson < ActiveRecord::Base
has_many :progresses
end
First, you need to set up the association for progress on your User model, so that the through association will work:
class User < ActiveRecord::Base
has_many :lessons
has_many :progress
has_many :points, through: :progress
end
Then you'll need to define a method (or relation) of points on your Progress table. Or, if you simply want a count of records, you could do: #user.points.size
I'm new to rails and working on an app that has the following situation:
Users have skills (e.g rafting, dancing)
Users participate in contests
Contest measures multiple skills
At the end of each contest, each user gets a score (e.g dancing: 5, rafting: 4)
Whats the best way to model this ?
Thanks,
This got nasty :s At the end I was actually not sure if this is the right way
class Skill < ActiveRecord::Base
has_many :skill_scores
has_many :user_skills
end
class UserSkill < ActiveRecord::Base
belongs_to :user
belongs_to :skill
end
class SkillScore < ActiveRecord::Base
belongs_to :user
belongs_to :contest
belongs_to :skill
end
class User < ActiveRecord::Base
has_many :skills
has_many :contests, :through => :contest_participations
has_many :skill_scores
end
class Contest < ActiveRecord::Base
has_many :users, :through => :contest_participations
has_many :skill_scores
end
class ContestParticipation < ActiveRecord::Base
belongs_to :user
belongs_to :contest
end