Create has_and_belongs_to_many and belongs_to both - ruby-on-rails

I have to build functionality where a user create a company and then many user can be associated with that company. It will be simple and can be done by has_and_belongs_to_many. But i also have to record and identify the user who has created that company. If you need any other information let me know

Make a separate association for the User representing the 'owner' of the Company:
class Company < ActiveRecord::Base
belongs_to :owner, class_name: 'User'
has_and_belongs_to_many :users
end
class User < ActiveRecord::Base
has_many :owned_companies, class_name: 'Company', foreign_key: :owner_id
has_and_belongs_to_many :companies
end

Related

Find all the users in an organization and it's suborganizations

A user belongs to an organization, which in turn can have multiple users and child organizations. How do you find all the organizations users?
I have the models named User and Organization. They have the following relationships:
In the user model:
belongs_to :organization
In the organization model:
has_many :users
has_many :child_organizations, class_name: "Organization", foreign_key:"parent_id"
belongs_to :parent, class_name: "Organization"
I want to find all users who belong to child_organizations of the current user organization.
#users = current_user.organization.child_organizations.users
It returns this error:
undefined method `users' for Organization::ActiveRecord_Associations_CollectionProxy:0x8f975d0
Based on the formatting of your question I'm not entirely sure what it is you have for you model relationships. But if you want to find all users whom belong to child_organizations of current_user's organization ...
This is how you can set up your relationships
class User < ActiveRecord::Base
belongs_to :organization
belongs_to :child_organization
end
class Organization < ActiveRecord::Base
has_many :child_organizations
has_many :users, through: :child_organizations
end
class ChildOrganization < ActiveRecord::Base
belongs_to :organization
has_many :users
end
And now you can use the following
#users = current_user.organization.users

How should I approach this relations in ruby?

I've been going back and forward on this and I would like some advices.
I have "User" that can be part of many "Organizations", and for each one they can have many "Roles". (actually I have this scenario repeated with other kind of users and with something like roles, but for the sake of the example I summed it up).
My initial approach was doing a Table with user_id, organization_id and role_id, but that would mean many registers with the same user_id and organization_id just to change the role_id.
So I thought of doing an organization_users relation table and an organization_users_roles relation. The thing is, now I don't exactly know how to code the models.
class Organization < ActiveRecord::Base
has_and_belongs_to_many :users, join_table: :organization_users
end
class User < ActiveRecord::Base
has_and_belongs_to_many :organizations, join_table: :organization_users
end
class OrganizationUser < ActiveRecord::Base
has_and_belongs_to_many :users
has_and_belongs_to_many :organizations
has_many :organization_user_roles
has_many :roles, through: :organization_user_roles
end
class OrganizationUserRole < ActiveRecord::Base
has_and_belongs_to_many :roles
has_and_belongs_to_many :organization_users
end
class Role < ActiveRecord::Base
has_and_belongs_to_many :organization_user_roles
end
If for example I want to get: ´OrganizationUser.first.roles´ I get an error saying: PG::UndefinedTable: ERROR: relation "organization_user_roles" does not exist
How should I fix my models?
You should use a much simpler approach. According to your description, Roles is actually what connects Users to Organizations and vice-versa.
Using the has_many and has_many :through associations, this can be implemented like the following:
class User < ActiveRecord::Base
has_many :roles, inverse_of: :users, dependent: :destroy
has_many :organizations, inverse_of: :users, through: :roles
end
class Organization < ActiveRecord::Base
has_many :roles, inverse_of: :organizations, dependent: :destroy
has_many :users, inverse_of: :organizations, through: :roles
end
class Role < ActiveRecord::Base
belongs_to :user, inverse_of: :roles
belongs_to :organization, inverse_of: :roles
end
If you wish to preserve roles when you destroy users or organizations, change the dependent: keys to :nullify. This might be a good idea if you add other descriptive data in your Role and want the role to remain even though temporarily vacated by a user, for example.
The has_many :through association reference:
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
To add to jaxx's answer (I upvoted), I originally thought you'd be best looking at has_many :through:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :positions
has_many :organizations, through: :positions
end
#app/models/position.rb
class Position < ActiveRecord::Base
#columns id | user_id | organization_id | role_id | etc | created_at | updated_at
belongs_to :user
belongs_to :organization
belongs_to :role
delegate :name, to: :role #-> #position.name
end
#app/models/organization.rb
class Organization < ActiveRecord::Base
has_many :positions
has_many :users, through: :positions
end
#app/models/role.rb
class Role < ActiveRecord::Base
has_many :positions
end
This will allow you to call the following:
#organization = Organization.find x
#organization.positions
#organization.users
#user = User.find x
#user.organizations
#user.positions
This is much simpler than your approach, and therefore has much more ability to keep your system flexible & extensible.
If you want to scope your #organizations, you should be able to do so, and still call the users / positions you need.
One of the added benefits of the code above is that the Position model will give you an actual set of data which can be shared between organizations and users.
It resolves one of the main issues with jaxx's answer, which is that you have to set a role for every association you make. With my interpretation, your roles can be set on their own, and each position assigned the privileges each role provides.
If the user can have many Roles for a single organisation,
and OrganizationUser represents this membership,
than, yes, you need another table for organization_user_roles.
You need to explicitly create it in the database (normally with a migration)
To not get confused, try to find a nice name for OrganisationUser, like employment, membership, etc.

Rails belongs_to and has_many foreign_key relationship

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.

How to do has_many and has_one association in same model?

I need to do two associations in the same model. Where:
Team has_many User
Now, I want that Team has_one Leader
This "Leader" will be a User
Im trying to use has_one throught but I think that association isn't work.
Leader.rb
class Leader < ActiveRecord::Base
belongs_to :user
belongs_to :team
Team.rb
class Team < ActiveRecord::Base
has_one :user, through: :leader
end
User.rb
class User < ActiveRecord::Base
belongs_to :team
has_one :captain
end
and the get following error around line 27:
NoMethodError in TeamsController#create
26 def create
**27 #team = current_user.teams.create(team_params)**
28 #team.save
29 respond_with(#team)
30 current_user.update(team_id: #team.id)
In this case I think you need 2 model are enough
1). User model
class User < ActiveRecord::Base
belongs_to :team
end
2). Team model
class Team < ActiveRecord::Base
has_many :users
belongs_to :leader, class_name: 'User', foreign_key: :leader_id
end
How about setting a boolean flag in users table called leader. And then your association can become:
class Team < ActiveRecord::Base
has_many :users
has_one :leader, class_name: 'User', -> { where leader: true }
end
Team has_many User Now, I want that Team has_one Leader
This "Leader" will be a User
Use inheritance (also called sub-classing), Leader is a User.
class User < ActiveRecord::Base
belongs_to :team
end
class Leader < User
end
class Team < ActiveRecord::Base
has_many :users
has_one :leader
end
Your users table is also important. Ensure that users has t.belongs_to :team and t.string :type in its create_table method. Note that a Leader is a User and does not need a separate table, however you do need to allow ActiveRecord to record its type so it can return the correct Model later.
References:
inheritance specifically you need 'single table inheritance'
belongs_to scroll down for has_one and has_many, the three relationships used here.
current_user.teams.create(team_params)
Teams is for a has_many association, you want current_user.create_team(team_params)
You have has_one association between user and team. Try this:
current_user.create_team(team_params)
Also, you should add proper back association from team to leader.
class Team < ActiveRecord::Base
belongs_to :leader
has_one :user, through: :leader
end

Rails - has_one and belongs_to for association

I have these two tables:
accounts
- user_id
users
- account_id
Many users can belong to an account and an account can have exactly one owner with full permissions. If a user owns an account, the two should reference each other. I'm trying to figure out how to set up this association. Here's what I have:
class Account < AR::Base
has_many :users
has_one :owner, class_name: 'User', foreign_key: :user_id
This seems right to me, but the User class is definitely not:
class User < AR::Base
belongs_to :account
has_one :account
An object can't belong to and have one at the same time. How should I set up my User class?
Following should work I think:
class Account < AR::Base
has_many :users
belongs_to :owner, class_name: 'User', foreign_key: :user_id
class User < AR::Base
belongs_to :account
has_one :account, inverse_of: :owner

Resources