Help with Rails ActiveRecord managing queries - ruby-on-rails

I have 3 models. Users, Groups, Employees all of the three have many to many.
user has many groups
groups have many users
groups have many employees
employees have many groups
So I've created two new models:
Departments (handles many to many between Users and Groups)
Employments (handles many to many between Groups and
Employees)
I believe I have this correct on paper but I can not get it down to code properly as I am new to rails. Because of this the data fetch does not seem to be correct.
This is what I have:
Employment:
class Employment < ActiveRecord::Base
belongs_to :group
belongs_to :employee
end
Department:
class Department < ActiveRecord::Base
belongs_to :group
belongs_to :user
end
User:
class User < ActiveRecord::Base
has_many :departments
has_many :groups, :through=>:departments
has_many :employees, :through=>:departments, :source => :group
end
Group:
class Group < ActiveRecord::Base
has_many :departments #new
has_many :users, :through => :departments #new
has_many :employments
has_many :employees, :through => :employments
end
Employee:
class Employee < ActiveRecord::Base
has_many :employments
has_many :groups, :through => :employments
end
I think biggest problem I have is to figure out how to get total employees for a user. In sql it would work with this query:
select * from employees where id in (select employee_id from employments where group_id in (select group_id from departments where user_id = 4))

This might work for you...
class User < ActiveRecord::Base
has_many :departments
has_many :groups, :through=>:departments **, :include => :employee**
has_many :employees, :through=>:departments, :source => :group
end
User.find(4).groups.collect { |c| c.employee.size }

Related

Rails - model relationship suggestion

Is it possible to define the following relationship:
A 'student' belongs to a 'group'
A 'group' has many 'courses' and many 'students'
A 'student' has many 'courses' through the 'group' it belongs to
I know how to do it with one more table(adding a student_course table which holds the id of the student and the course it belongs to and then saying that the a student has_many :courses, through: :student_course).
In other words, could it be implemented just by editing the following tables?
class Student
belongs_to :group
end
class Group
has_many :students
has_many :courses
end
class Course
belongs_to :group
end
Not sure if you can do it with a Rails class method, but you can just implement it manually.
class Student
belongs_to :group
def courses
group.courses
end
end
class Group
has_many :students
has_many :courses
end
class Course
belongs_to :group
end
Try below associaion
student.rb
belongs_to :group
has_many :courses, through: :group
group.rb
has many :courses
has many :students
course.rb
belongs_to :group
has_many :students, through: :group

has_and_belongs_to_many and has_many_through between the same models?

I have a model person and a model group. There are two kinds of persons: leaders lead a group and participants participate. I need a hbtm-relationship between leaders and groups and a has_many-relationship between participants and groups. Is it possible to do this with the same model, person by providing some kind of condition (is a leader/is a participant) in the model?
class Person < ActiveRecord::Base
has_and_belongs_to_many :groups
has_many :participations
has_many :groups, :through => :participations
...
end
I would like to do this with one model, person, because users are either leaders or participants but each user should be a person, i.e. User belongs_to :person.
you should only one class for persons, not more. You can do something like:
class Person < ActiveRecord::Base
has_many :relations
has_many :groups, :through => :relations
...
end
class Group < ActiveRecord::Base
has_many :relations
has_many :persons, :through => :relations
...
end
class Relation < ActiveRecord::Base
belongs_to :person
belongs_to :group
end
table 'relations' should have next to person_id and group_id, one more field, called, for example 'leader' and the value should be true/false or 1/0. So, if the person of the group is leader, the value should be 1/true, if not then 0/false

How to use Includes with activerecord associations?

given two models:
User
has_many :group_members
has_many :groups, :through => :group_members
GroupMember
belongs_to :group
belongs_to :user
Group
has_many :group_members
has_many :users, :through => :group_members
has_many :group_invites
GroupInvite
belongs_to :user
Thanks to Rails, I can easily get all of a user's groups with:
groups = current_user.groups
I then take this list of groups and iterate through to create a JSON object like so:
groups.each do |group|
....
group.group_members.count
group.invites.first_code
etc etc . The problem is this results in a large number of queries because I haven't found a way to use includes(:) to query for all the group_members and invites for all the groups with one query versus a query for every each loop. Any suggestions on how you can use includes like so:
current_user.groups.includes(:group_members, :invites) ?
Try this:
GroupMember
belongs_to :group
belongs_to :user
Group
has_many :group_members
has_many :users, :through => :group_members
has_many :invites, :
has_many :invitees, :through => :invites, :source => :user
Invite
belongs_to :group
belongs_to :user
Now you can:
current_user.groups.includes(:invitees)

What's the best way to make Rails 3 / Active Record associations for classes of a simple point of sale program?

I have 5 classes that are part of a point of sales program:
Customer, Technician, Order, Ticket, Service
Each Order has one customer and many tickets. Each Ticket has on technician and many services.
How should I make the associations so that I can do the following lookup:
customer.order.find_by_date(10/20/2010).service.technician.name
This is what I am planning:
class Customer < ActiveRecord::Base
has_many :orders
has_many :tickets, :through => :orders
has_many :technicians, :through => :tickets
end
class Technician < ActiveRecord::Base
belongs_to :ticket
belongs_to :service
end
class Service < ActiveRecord::Base
has_many :technicians
belongs_to :ticket
end
class Ticket < ActiveRecord::Base
has_many :services
has_many :technicians, :through => :services
end
class Order < ActiveRecord::Base
has_many :tickets
has_many :services, :through => tickets
has_many :technicians, :through => services
belongs_to :customer
end
The relationship between customer and order is one-to-many. And the relationship between order and service is also one-to-many. Therefore you cannot do:
customer.order.find_by_date('10/20/2010').service.technician.name
It should be:
customer.orders.find_by_date('10/20/2010').services.each do |service|
service.technician.name
end
It's a similar problem as in your other question.

Rails ActiveRecord Model design

I have 3 models. Users, Groups, Employees all of the three have many to many.
user has many groups
groups have many users
groups have many employees
employees have many groups
So I've created two new models:
Departments (handles many to many between Users and Groups)
Employments (handles many to many between Groups and
Employees)
I believe I have this correct on paper but I can not get it down to code properly as I am new to rails. Because of this the data fetch does not seem to be correct.
This is what I have:
Employment:
class Employment < ActiveRecord::Base
belongs_to :group
belongs_to :employee
end
Department:
class Department < ActiveRecord::Base
belongs_to :group
belongs_to :user
end
User:
class User < ActiveRecord::Base
has_many :departments
has_many :groups, :through=>:departments
has_many :employees, :through=>:departments, :source => :group
end
Group:
class Group < ActiveRecord::Base
has_many :departments #new
has_many :users, :through => :departments #new
has_many :employments
has_many :employees, :through => :employments
end
Employee:
class Employee < ActiveRecord::Base
has_many :employments
has_many :groups, :through => :employments
end
I think biggest problem I have is to figure out how to get total employees for a user. In sql it would work with this query:
select * from employees where id in (select employee_id from employments where group_id in (select group_id from departments where user_id = 4))
If you defined your many-to-many ActiveRecord model correctly.
You can do this to find the employees that are associated with the user:
#user = User.find(params[:id])
#employees = #user.employees
If you would like to tweak your queries, check out this doc - http://guides.rubyonrails.org/active_record_querying.html
This will allow you to do everything from eager/lazy loading, joining, grouping, limiting, etc.
If you want to use your original SQL to figure things out before you write cleaner code, check out the "finding-by-sql" section on the same page.

Resources