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.
Related
I need a little help... I have these relationships... Users belong to Department, a Department has a manager, Managers (Users) can have many managed departments.
I'm having one of those days and I can't for the life of me figure out what to put inside the User model to define the `has_many :managed_departments' part of the relationship.
Department
class Department < ActiveRecord::Base
has_many :users
belongs_to :manager, foreign_key: "manager_id", class_name: "User"
end
User
class User < ActiveRecord::Base
belongs_to :department
# has_many :managed_departments
end
This works: Department.last.manager which returns:
=> #<User id: 2, etc...
I'm having a mindblank on what to put in the User model.
Can anyone help?
You can use class_name option same like you used it in Department model
#user.rb
class User < ActiveRecord::Base
belongs_to :department
has_many :managed_departments, class_name: "Department", foreign_key: "manager_id"
end
You are not creating right association. You have many to many relation ship between user and department.
user has_many departments (Can manage multiple department)
department has_many users
As a database standard you should break many to many relationship and introduce a new intermediate table.
So your new table should be users_departments. In this table you can add column user is manager or not.
table should have column :
user_id , department_is, is_manager
class Department < ActiveRecord::Base
has_many :users, :through => :users_departments
end
class User < ActiveRecord::Base
has_many :departments, :through => :users_departments
end
class UsersDepartment < ActiveRecord::Base
belongs_to :user
belongs_to :department
end
Here you can find anything with association. and with simple scope you can find manager of department also.
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
After reading RailsGuides, some answers here and other docs I am still confused about how to model this relationship.
Thinking of a model where there are objects User and Group, where users can be ordinary members of a group or have management privilege (create group, invite user, remove user, remove group) I want both objects to have two many-many relationships with each other.
user.memberOfGroups = a list of groups the user belongs to
group.userMembers = a list of all users who are members of the group
user.managedGroups = a list of groups the user has management
privileges for
group.managingUsers = a list of users with management privilege for
the group
Is this going to work?
class User < ActiveRecord::Base
has_many :managedGroups, :class_name => "Group", :foreign_key => "managingUsers"
has_many :memberOfGroups, :class_name => "Group", :foreign_key => "userMembers"
end
class Group < ActiveRecord::Base
has_many :managingUsers, :class_name => "User", :foreign_key => "managedGroups"
has_many :userMembers, :class_name => "User", :foreign_key => "memberOfGroups"
end
I have found in a guide how to use scaffold to generate the model objects which is fine with me, I just want to create a basic web service for POST and GET. If the above is correct it should be as simple as creating the model with scaffold and then editing to include the lines shown?
Some issues:
Membership and access control should be modeled by different tables.
Does management of a group imply membership?
The foreign key design as described would only allow for each user to manage one group/one group to have one manager. In all many:many relationships you'll need a third join model.
This would be a good starting point:
class User < ActiveRecord::Base
has_many :users_groups
has_many :groups, :through => :users_groups
end
class Group < ActiveRecord::Base
has_many :users_groups
has_many :users, :through => :users_groups
end
class UsersGroup < ActiveRecord::Base # will be the users_groups table
belongs_to :user
belongs_to :group
end
class Permission < ActiveRecord::Base
belongs_to :user
belongs_to :group
validate_presence_of :name # The name of the permission e.g. "manage"
end
My current Group model:
class Group < ActiveRecord::Base
has_many :memberships, :dependent => :destroy
has_many :users, :through => :memberships
end
My Current User Model
class User < ActiveRecord::Base
has_and_belongs_to_many :roles
has_many :memberships, :dependent => :destroy
has_many :groups, :through => :memberships
#some more stuff
end
Membership Model
class Membership < ActiveRecord::Base
attr_accessible :user_id, :group_id
belongs_to :user
belongs_to :group
end
Role Model
class Role < ActiveRecord::Base
has_and_belongs_to_many :users
end
I have a Ability class and CanCan installed to handle roles. I have a role type groupleader and need to make sure a Group has only one groupleader...
I think its something like: Group has_one User.role :groupleader... but I know thats not it.
It doesn't make sense to me to have the role on the users table if you want it to determine what the user can do within the context of a group.
Where it would make sense is to have it on the memberships table for groups and users. Records in this table would then have three columns: user_id, group_id and role.
Then to retrieve the leader for the group you would execute a query like this:
group.users.where("memberships.role = 'leader'").first
Where group is a Group object, i.e. Group.first or Group.find(13).
This then leaves open the possibility that you can have more than one leader for a group further down the track if required.
If your roles are in a separate table, then you can do this:
group.users.where("memberships.role_id = ?", Role.find_by_name("leader").id).first
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 }