Having some challenges, need to keep track of the courses an Employee have taken. This is what i have these tables so far
Course: course_id,name,category_of_course...#holds Course related details
Employee: employee_id, name...#holds Employee details
progress:course_id,employee_id, status ...#holds which course have been
taken and by whom
in My Models, i have this relationships:
Employee: has_many :courses
Please how do i populate a Select List with the Courses that an Employee have not taken(assuming after registering for a course, it's flagged as taken). Im using rails 3.0.9 with MySql.
Thank You
You need to define
belongs_to :employee
belongs_to :course
(in your progress model)
You can then define
#Employee
has_many :progresses
has_many :courses, :through => :progresses
#Course
has_many :progresses
has_many :employees, :through => :progresses
The select list will be:
= form_for #something do |f|
= f.select :course_id, Course.all.select{|x| not #employee.courses.include?(x)}.collect{|x|[x.name,x.id]} #Ideally this logic should reside in the model.
Related
I have the following Rails Model Relation:
class Grade < ApplicationRecord
has_and_belongs_to_many students, join_table: :grade_student_mappings
has_many :students
end
class Student < ApplicationRecord
has_and_belongs_to_many :grads, join_table: :grade_student_mappings
belongs_to :grade
end
Now when I want to access the grade table and the student table using the join_table - rails will fail.
Example: Grade.find_by_id(1).student will always response me the content of the direct relation between Grade and Student. The Relation via the join_table will be ignored.
Only when I uncomment the model line has_many and belongs_to then the indirect relation via the join_table will be considered.
How I can say to RAILS, which relation between Grade and Student I want to use ?
Rails supports two kinds of many-to-many relationships. has_many through and has_and_belongs_to_many. You are mixing the two. You need to pick one and the more flexible one is has_many through. Change your model files to the following:
# app/models/grade_student_mapping.rb
belongs_to :grade
belongs_to :student
# app/models/grade.rb
has_many :grade_student_mappings, dependent: :destroy
# app/models/student.rb
has_many :grade_student_mappings, dependent: :destroy
has_many :grades, through: :grade_student_mappings
Then you can access the student's grades on their show template for example by setting the grades instance variable in the students_controller show action
# app/controllers/students_controller.rb
def show
#grades = #student.grades
end
And display the grades on the student's show page. Something like the below:
# app/views/students/show.html.erb
<% #grades.each do |grade| %>
<%= grade.semester %>
<%= grade.course %>
<%= grade.letter %>
<% end %>
I have a relationship model in which students and employers can enter into a relationship when applying to a project. Here are the models:
class Student < User
has_many :relationships, dependent: :destroy
has_many :employers, through: :relationships
end
class Employer < User
has_many :projects
has_many :relationships, dependent: :destroy
has_many :students, through: :relationships
end
class Relationship < ActiveRecord::Base
has_one :project
belongs_to :employer
belongs_to :student
validates_uniqueness_of :project_id, :scope => [:employer_id, :student_id]
end
class Project < ActiveRecord::Base
belongs_to :employer
end
State is a column in the projects table that is automatically set equal to 'posting'. I am trying to show all relationships that have a project with state == :posting. Here is my view code:
<% #relationships.each do |relationship| %>
<% if relationship.project.state == :posting %>
<%= relationship.project.inspect %>
<% end %>
<% end %>
Also, in the controller for this view is:
#relationships = Relationship.all
When i try to open the view, i get:
PG::UndefinedColumn: ERROR: column projects.relationship_id does not exist
What doesn't make sense to me is that I am not looking in the projects table for a relationship_id column. My code should find the project from the relationship and then find the state column. I have relationships has_one :project but i don't have :projects belongs_to relationships because a project does not need a relationship in order to exist. I'm pretty sure my database relations are right. How do I fix my view code? Or, if my db relationships are wrong, what's wrong?
Update
i forgot to mention that Employer and Student are both User models through polymorphic association. The user model has a type column that can be either Student or Employer.
When you declare that Relationship has_one :project, you are telling Rails that the Project model (and the corresponding projects database table) has a relationship_id field . When you refer to relationship.project in your view, you cause that table/field to be referenced, resulting in your error.
Given that each relationship should indeed have just one project associated with it, you should declare Project as belongs_to :relationship, create the appropriate migration and update your code accordingly to maintain the value of this field.
At first glance it seems like it should be
class Employer < User
has_many :projects, through: :relationships
for this to work. Am I missing something?
I have a rails 3 application.
I have the following scenario: There are students and teachers who have interactions. Based on some of these interactions, a teacher may elect to give a student a reward, i.e. a student_reward.
class Student
has_many :interactions
has_many :teachers, :through=>:interaction
class Teacher
has_many :interactions
has_many :students, :through=>:interaction
has_many :rewards
class Interaction
belongs_to :teacher
belongs_to :student
has_many :student_rewards
has_many :rewards, :through=>:student_reward
class Reward
belongs_to :teacher
has_many :student_rewards
class StudentRewards
belongs_to :reward
belongs_to :interaction
How would an expert code an efficient approach to fetching all of the rewards that a student's teachers have [not necessarily ones that the student has won] and also list info on the teachers in the display?
I tried this, but I have to separately get the teacher information in the view, and this is bad. (assuming the student_id=1):
#rewards = Reward.joins(:teacher => :interactions)
.where("interactions.student_id=1")
.paginate(:page => params[:page], :per_page => 5)
Questions:
Is this the best way to do it?
When I am iterating through this in the view, I have to issue additional queries to display information about the teacher [name, deomographics]. How can I fetch this more efficiently?
I want to be able to do this:
<% for reward in #rewards%>
<%= reward.name, reward.teacher.name, reward.teacher.bio%><br>
<%end%>
If you have the student, then getting the rewards for the student's teacher is easily obtained like so:
#student = Student.find(1)
#rewards = []
#rewards += #student.teachers.collect {|teacher| teacher.rewards }
The relationship you set in Student has_many :teachers, :through=>:interaction makes this possible.
I have a User model, Person model and Company model.
a User has many companies through Person and vice versa.
But i would like to be able to populate People and Companies that are not tied to Users that can be tied later.
class User < ActiveRecord::Base
attr_accessible :name
has_many :people
has_many :companies, :through => :people
end
class Person < ActiveRecord::Base
attr_accessible :user_id, :company_id
belongs_to :users
belongs_to :companies
end
class Company < ActiveRecord::Base
attr_accessible :name
has_many :people
has_many :users, :through => :person
end
now in the console i want to be doing the following
User.find(1).companies
then it should find me the companies in which user(1) is a person of interest.
Have I got this wrong, is there a small change that I should be making.
Your Person model can't directly "belong_to" more than one, your belongs_to :users and belongs_to :companies associations won't work that way. Companies-to-people need to be connected through another join table that describes the relationship between them, for example Employment which points to one instance of each model:
class Person < ActiveRecord::Base
has_many :employments
has_many :companies, :through => :employments
end
class Employment < ActiveRecord::Base
belongs_to :person
belongs_to :company
end
class Company < ActiveRecord::Base
has_many :employments
has_many :people, :through => :employments
end
You can then use the :through option to associate the many companies/people on the other side of that employment relationship in the middle.
Similarly, if a Person can be owned by more than one User then you will need a join model between those two entities as well.
Just as a followup, in a has_many :through relationship, there is nothing that says you cannot use your join table (in your case, Person) independently. By nature of the relationship, you are joining through a completely separate ActiveRecord model, which is what most notably distinguishes it from the has_and_belongs_to_many relationship.
As Brad pointed out in his comment, you need to pluralize 'person' to 'people' in your relationship. Other than that, it looks like you set it up correctly. Exposing :user_id and :company_id with attr_accessible will enable you to mass-assign these values later from a postback, but often times you want to shy away from doing so with role-based associations, as you may not want to leave them exposed to potential HTTP Post attacks.
Remember, in your controller you can always do something like this with or without attr_accessible:
#person = Person.new
#person.user = User.find(...)
#person.company = Company.find(...)
#person.save
Hope that helps.
This is the structure of my database in Ruby on Rails:
user have many notes
notes have many categories
categories have many notes
The relationship between notes and categories is has_many :through, I have a model named NoteCategory and a note_categories table.
The note model has a date field, which represents the date the note was created.
I get the notes for the user with this line:
current_user.notes
How can I provide a date and get back the categories for all the user's notes that were created on that date? Thanks for reading.
edit: Forgot to mention that I also need the categories to be ordered by the created_at field of the note they are attached to.
edit 2: here are the actual associations
user.rb
has_many :notes
note.rb
belongs_to :user
has_many :note_categories
has_many :categories, :through => :note_categories
category.rb
has_many :note_categories
has_many :notes, :through => :note_categories
Given you have
class User
has_many :notes
has_many :categories, :through => :notes
end
class Note
has_many :categories # <-- source reflection
end
then use this finder:
user.categories.all(:order => 'notes.created_at')
or
user.categories.find :all, :order => 'notes.created_at'