Many to Many, Through Relationship for Users - ruby-on-rails

On Rails 4, I am using devise for my users and I have a scaffold for exercises.
Each user is to have many exercises, and each exercises have many users, this is done through a model called schedule.
I want to build a form, so that when a new exercise is created then it can be assigned to the Users. I am little lost on how to allow the schedule table to accept both the exercise_id and user_id when I create a new exercise. Any help is appreciated!
/user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :schedules
has_many :exercises, :through => :schedules
/exercise.rb
class Exercise < ActiveRecord::Base
validates :description, presence: true
has_many :schedules
has_many :users, :through => :schedules
/schedules.rb
class Schedule < ActiveRecord::Base
belongs_to :exercise
belongs_to :user
Exercise Controller
def exercise_params
params.require(:exercise).permit(:description, :notes, :video, {:users=>[]})
end
edit
I am lost as what to do next in order to get the Schedule table to populate with Exercise_ids and User_ids.
Schema:
USERS
id
email
name
(standard columns from devise)
EXERCISES
id
description
created_at
updated_at
tag
notes
video_file_name
video_content_type
video_file_size
video_updated_at
SCHEDULE
id
exercise_id
user_id
position
created_at
updated_at

Related

Cannot create has_one association, throws undefined method new error

I'm trying to build a one to one association in Rails 5, basically, I just want users to connect to only one user.
So I want to be able to do this in my rails console:
User.first.relationship.new(:partner_id => 2)
To be able to set and retrieve the partner of a particular user.
I'm using a join model, called Relationship.
class Relationship < ApplicationRecord
belongs_to :user
belongs_to :partner, :class_name => "User"
end
And a User model.
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:confirmable
has_one :relationship
has_one :partner, :through => :relationship
validates_presence_of :first_name, :last_name
end
I generated the Relationship model like this: rails g model Relationship user:references partner_id:integer.
When I do a User.first.relationship.new() it throws a NoMethodError: undefined method new for nil:NilClass in the rails console.
However, when I change the User model from has_one to has_many:
has_many :relationships
has_many :partners, :through => :relationships
It works, but I want to have only a one to one relationship using a self-referential association.
What am I doing wrong? Thanks!
Try User.first.create_relationship(relationship_params) ?

Rails best way (or best practices)

I have a model which I don't know how to focus the following issue:
I have been reading the following posts
before_create in rails model
before_create in user model -- set integer based on email (RAILS)
Access current_user in model
I have a project where I want to manage some properties (Assets).
I have Property, Owner, Company and Users.
The House and the Owner are linked in the DB with a FK so 1 Company has N Owners and 1 Company has N Properties.
The model User is linked to Company, so 1 Company has N users.
How can I access the company_id in the model Users in order to store this ID in the Properties and in the Owner model when the Property and Owner is created?
Do I have to do it in the controller and model?
Owner Class
class Owner < ApplicationRecord
acts_as_paranoid
has_many :property_owners
has_many :properties, :through => :property_owners
belongs_to :company
belongs_to :country
accepts_nested_attributes_for :properties
Property Class
class Property < ApplicationRecord
acts_as_paranoid
has_many :property_owners has_many :owners, :through =>
:property_owners
belongs_to :company belongs_to :country
This is the Company
Class Company < ApplicationRecord
has_many :properties
has_many :owners
And the last one is Users
class User < ApplicationRecord
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
before_create :set_default_role, only: :create
belongs_to :country
belongs_to :company
belongs_to :user_role
accepts_nested_attributes_for :company
Considering you have your associations right, in your controller, when a user creates, for example, a house entry:
def create
#property = current_user.company.properties.new(property_params)
....
end
Where current_user can be replaced by the variable containing the user currently logged on and property_params are the strong params, sent to the controller from your form.
Likewise for owner

Get values from a has_many through relation

My setup:
class ServiceUser < ActiveRecord::Base
belongs_to :user
belongs_to :service
enum status: [ :unavailable, :available ]
end
class Service < ActiveRecord::Base
has_many :service_users
has_many :users, :through => :service_users
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :service_users
has_many :services, :through => :service_users
end
From the ServiceUser model i can call the status field, in my case available and unavailable.
In my app i'm listing all the users for a specific service with:
#service.users
But now i want to show the status for each user from the ServiceUser model. What is the best way to do is?
Also i want to make a form for the ServiceUser model to make a new relation between the service and the current user:
ServiceUser.new(service_id: #service.id, user_id: current_user.id, status: 1)
What do i need to specify in the form for?
Construct a hash with user_id as the key and value as the status
user_status = Hash[*#service.service_users.map{|su|[su.user_id, su.status] }.flatten]
Now you can get the status for each user by
#service.users.each do |user|
p user_status[user.id]
end

How to use owner_id (instead of user_id) as foreign key?

I'm building an app where a user creates an arbitrary number of groups. When the group is created, the owner_id (in the group table) is set to that of the current_user.id.
I'm having some trouble showing the groups owned by a particular user though. Note that there is a many-to-many relationship between users and groups through the GroupMembers table.
Based on this question, I modified my group.rb model like such:
class Group < ActiveRecord::Base
has_many :group_members, :dependent => :destroy
has_many :users, :through => :group_members
belongs_to :owner, class_name: User, foreign_key: :owner_id
end
Adding just the last line to ("owner") to the model. The problem is that when I display the groups belonging to the user in my view:
<h3>User</h3>
<p>User: <%= #user.name %></p>
<p>Email: <%= #user.email if #user.email %></p>
<p>Groups:
<% #user.groups.each do |group|%>
<%= group.name %>
<% end %>
</p>
None of the groups show up. It seems that maybe I need to explicitly join to the groups table from inside the UsersController for this to work? But I'm not sure. I don't want to go too far down the rabbit hole here so I'm looking for some advice.
UPDATE:
Here is my User model:
class User < ActiveRecord::Base
has_many :group_members, :dependent => :destroy
has_many :groups, :through => :group_members
rolify
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :invitable, :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
end
When you fetch #user.groups, you're using the :groups association on the User model, which is independent of the has_one :user association on the Group model. So the code you've provided above isn't the relevant bit. What you need is:
class User < ActiveRecord::Base
has_many :groups, foreign_key: :owner_id
end
Update: since you've already got a has_many :groups relation, you'll need to name this something else. e.g.,
class User < ActiveRecord::Base
has_many :owned_groups, foreign_key: :owner_id, class_name: Group
end
Then you'll need to update your view code to do #user.owned_groups instead of #user.groups, or you'll be fetching the wrong collection.
(p.s., the inverse relation on the Group model should be belongs_to :owner, class_name: User, foreign_key: :owner_id, not has_one. The difference is that a model that belongs_to another model is expected to hold the foreign key that defines the relationship, whereas a has_one relationship expects the foreign key to be on the associated table.)
You can do something like
# user.rb
has_many :owned_groups, foreign_key: 'owner_id', class_name: "Group"
That will distinguish between groups that the user owns vs groups that the user is in.

deciding team lead and assigning users to team in ruby on rails

I want to assign a team lead and members(users) to team. I have created "has many and through" association between teams and users tables as one team may have many users and a user can be assigned to many teams. For getting team lead for every team, I have put team_lead column in teams table.
Doubts: 1. Is this right way to put team_lead column in teams table to assign team lead to a team , when team is being created.
When a team is created, It will have a team lead and some users which are already existed in db. How to assign users to team ?
user.rb
class User < ActiveRecord::Base
has_many :teams, through: :user_teams
has_many :user_teams
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :username, :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :is_admin, :contact_no, :birth_date, :joining_date, :is_active, :is_hr, :is_manager
# attr_accessible :title, :body
end
team.rb
class Team < ActiveRecord::Base
attr_accessible :name
has_many :user_teams
has_many :users, through: :user_teams
end
team_user.rb
class TeamsUser < ActiveRecord::Base
attr_accessible :team_id, :team_lead, :user_id
belongs_to :user
belongs_to :team
end
At the time of team creation, I want to assign a team lead and users to a team. How to implement this. Any help would be appreciated. Thanks.
You can more easily model a many-to-many relationshop between users and teams using has_and_belongs_to_many.
Then your models would look like this:
class User
has_and_belongs_to_many :teams
...
end
class Team
has_and_belongs_to_many :users
has_one :team_lead, class_name: "User"
...
end
Note that Team also has a team_lead, which is also of type User.
Then it's easy to create a new team with team lead:
team = Team.new
team.team_lead = existing_user1
team.users << existing_user2
team.save
To make the many-to-many relationship work you'll also need a join table called teams_users. See the Rails documentation for more information on setting up the many-to-many relationship.

Resources